xeps/xep-0116.xml

949 lines
65 KiB
XML
Raw Normal View History

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
<!ENTITY esupy "e<span class='super'>y</span>">
<!ENTITY dsupx "d<span class='super'>x</span>">
<!ENTITY gsupx "g<span class='super'>x</span>">
<!ENTITY gsupy "g<span class='super'>y</span>">
<!ENTITY NsubA "N<span class='sub'>A</span>">
<!ENTITY NsubB "N<span class='sub'>B</span>">
<!ENTITY CsubA "C<span class='sub'>A</span>">
<!ENTITY CsubB "C<span class='sub'>B</span>">
<!ENTITY MsubA "M<span class='sub'>A</span>">
<!ENTITY MsubB "M<span class='sub'>B</span>">
<!ENTITY KMsubA "KM<span class='sub'>A</span>">
<!ENTITY KMsubB "KM<span class='sub'>B</span>">
<!ENTITY KCsubA "KC<span class='sub'>A</span>">
<!ENTITY KCsubB "KC<span class='sub'>B</span>">
<!ENTITY KSsubA "KS<span class='sub'>A</span>">
<!ENTITY KSsubB "KS<span class='sub'>B</span>">
<!ENTITY twosup32 "2<span class='super'>32</span>">
<!ENTITY twosup2n "2<span class='super'>2n-1</span>">
<!ENTITY CBeCAx2n1 "&CsubB; = &CsubA; XOR 2<span class='super'>n-1</span>">
<!ENTITY IDA "ID<span class='sub'>A</span>">
<!ENTITY IDB "ID<span class='sub'>B</span>">
<!ENTITY formA "form<span class='sub'>A</span>">
<!ENTITY formB "form<span class='sub'>B</span>">
<!ENTITY macA "mac<span class='sub'>A</span>">
<!ENTITY macB "mac<span class='sub'>B</span>">
<!ENTITY signA "sign<span class='sub'>A</span>">
<!ENTITY signB "sign<span class='sub'>B</span>">
<!ENTITY signsA "signs<span class='sub'>A</span>">
<!ENTITY signsB "signs<span class='sub'>B</span>">
<!ENTITY pubKeyA "pubKey<span class='sub'>A</span>">
<!ENTITY pubKeyB "pubKey<span class='sub'>B</span>">
<!ENTITY signKeyA "signKey<span class='sub'>A</span>">
<!ENTITY signKeyB "signKey<span class='sub'>B</span>">
<!ENTITY pubKeysA "pubKeys<span class='sub'>A</span>">
<!ENTITY signKeysA "signKeys<span class='sub'>A</span>">
<!ENTITY x1xZ "x<span class='sub'>1</span>...x<span class='sub'>Z</span>">
<!ENTITY e1eZ "e<span class='sub'>1</span>...e<span class='sub'>Z</span>">
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Encrypted Session Negotiation</title>
<abstract>This document specifies an XMPP protocol extension for negotiating an end-to-end encrypted session.</abstract>
&LEGALNOTICE;
<number>0116</number>
<status>Experimental</status>
<type>Standards Track</type>
<jig>Standards JIG</jig>
<dependencies>
<spec>XMPP Core</spec>
<spec>XMPP IM</spec>
<spec>RFC 2104</spec>
<spec>RFC 2409</spec>
<spec>RFC 3526</spec>
<spec>RFC 3548</spec>
<spec>SHA256</spec>
<spec>xml-c14n</spec>
<spec>XEP-0004</spec>
<spec>XEP-0020</spec>
<spec>XEP-0030</spec>
<spec>XEP-0068</spec>
<spec>XEP-0155</spec>
<spec>XEP-0200</spec>
</dependencies>
<supersedes>None</supersedes>
<supersededby>None</supersededby>
<shortname>esession</shortname>
&ianpaterson;
&stpeter;
&dizzyd;
<revision>
<version>0.13</version>
<date>2006-11-23</date>
<initials>ip</initials>
<remark><p>Added disclosure field; added Back Doors and Key Associations sections; employed HMAC instead of hash; moved exchanging stanzas and rekeying sections to XEP-0200; changed namespace</p></remark>
</revision>
<revision>
<version>0.12</version>
<date>2006-10-05</date>
<initials>ip</initials>
<remark><p>Replaced secure field with security field; changed otr field to list-single</p></remark>
</revision>
<revision>
<version>0.11</version>
<date>2006-10-02</date>
<initials>ip</initials>
<remark><p>Harmonised session termination with the protocol added to XEP-0155; added XML schema; minor clarifications</p></remark>
</revision>
<revision>
<version>0.10</version>
<date>2006-07-18</date>
<initials>ip</initials>
<remark><p>Added Upgradability requirement; added expires field to offline options; updated in line with latest version of PEP; moved some content to new XEPs (0187, 0188 and 0189)</p></remark>
</revision>
<revision>
<version>0.9</version>
<date>2005-11-29</date>
<initials>ip</initials>
<remark><p>Modified protocol in line with SIGMA: added Identity Protection requirement, no pre-indication of acceptable keys, send multiple values of e with ESession request, offline options published via SPPS, added LZW compression</p></remark>
</revision>
<revision>
<version>0.8</version>
<date>2005-09-27</date>
<initials>ip</initials>
<remark><p>Added diagramatic synopses; Added match_resource field; replaced req_mac and kid fields with prev_hash; Alice specifies initial counter (doubles as nonce); many other improvements</p></remark>
</revision>
<revision>
<version>0.7</version>
<date>2005-08-26</date>
<initials>ip</initials>
<remark><p>Simplified XML normalization; added Synopsis and Efficiency requirement; defined signature formats</p></remark>
</revision>
<revision>
<version>0.6</version>
<date>2005-08-12</date>
<initials>ip</initials>
<remark><p>Extended termination procedure; added object encryption/signing requirement and special case; clarified expired MAC publishing; added Flexible Offline Message Retrieval to Open Issues.</p></remark>
</revision>
<revision>
<version>0.5</version>
<date>2005-08-10</date>
<initials>ip</initials>
<remark><p>Added flexibility requirement; added late signature of initial request; added termination MAC.</p></remark>
</revision>
<revision>
<version>0.4</version>
<date>2005-08-09</date>
<initials>ip</initials>
<remark><p>Added (offline) replay protection; required offline Created header; compression is NOT RECOMMENDED; added second set of offline options for subscribers; added JIDs to session key generation; unencrypted sessions; added secure option; sign whole data form; HMAC whole &lt;encrypted/&gt; element; added ESession termination; option to distribute public keys within session negotiation; added Integrity requirement; several clarifications</p></remark>
</revision>
<revision>
<version>0.3</version>
<date>2005-08-02</date>
<initials>ip/psa</initials>
<remark><p>Restored status to Experimental; complete rewrite; new Introduction, Background, Requirements and Security Considerations; new OTR-inspired protocol; XEP-0155-based negotiation; counter mode encryption; more secure hashes; offline sessions; re-keying; mac publishing; preliminary key and options publishing protocol.</p></remark>
</revision>
<revision>
<version>0.2</version>
<date>2004-07-26</date>
<initials>psa</initials>
<remark><p>At the request of the author, changed status to Retracted.</p></remark>
</revision>
<revision>
<version>0.1</version>
<date>2003-09-09</date>
<initials>dss/psa</initials>
<remark><p>Initial version.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>End-to-end encryption is a desirable feature for any communication technology. Ideally, such a technology would design encryption in from the beginning and would forbid unencrypted communications. Realistically, most communication technologies have not been designed in that manner, and Jabber/XMPP technologies are no exception. In particular, the original Jabber technologies developed in 1999 did not include end-to-end encryption by default. PGP-based encryption of message bodies and signing of presence information was added as an extension to the core protocols in the year 2000; this extension is documented in &xep0027;. When the core protocols were formalized within the Internet Standards Process by the IETF's XMPP Working Group in 2003, a different extension was defined using S/MIME-based signing and encryption of CPIM-formatted messages (see &rfc3862;) and PIDF-formatted presence information (see &rfc3863;); this extension is specified in &rfc3923;.</p>
<p>For reasons described in &xep0188;, the foregoing proposals (and others not mentioned) have not been widely implemented and deployed. This is unfortunate, since an open communication protocol needs to enable end-to-end encryption in order to be seriously considered for deployment by a broad range of users.</p>
<p>This proposal describes a different approach to end-to-end encryption for use by entities that communicate using XMPP. The requirements and the consequent cryptographic design that underpin this protocol are described in <cite>Cryptographic Design of Encrypted Sessions</cite>. The basic concept is that of an encrypted session which acts as a secure tunnel between two endpoints. Once the tunnel is established, the content of each one-to-one XML stanza exchanged between the endpoints will be encrypted and then transmitted within a "wrapper" stanza using &xep0200;.</p>
</section1>
<section1 topic="Dramatis Personae" anchor='personae'>
<p>This document introduces two characters to help the reader follow the necessary exchanges:</p>
<ol start='1'>
<li>"Alice" is the name of the initiator of the ESession. Within the scope of this document, we stipulate that her fully-qualified JID is: &lt;alice@example.org/pda&gt;.</li>
<li>"Bob" is the name of the other participant in the ESession started by Alice. Within the scope of this document, his fully-qualified JID is: &lt;bob@example.com/laptop&gt;.</li>
<li>"Aunt Tillie" the archetypal typical user (i.e. non-technical, with only very limited knowledge of how to use a computer, and averse to performing any procedures that are not familiar).</li>
</ol>
<p>While Alice and Bob are introduced as "end users", they are simply meant to be examples of XMPP entities. Any directly addressable XMPP entity may participate in an ESession.</p>
</section1>
<section1 topic='Discovering Support' anchor='disco'>
<p>Before attempting to engage in an ESession with Bob, Alice MAY discover whether he supports this protocol, using either &xep0030; or the presence-based profile of <cite>XEP-0030</cite> specified in &xep0115;.</p>
<p>The normal course of events is for Alice to authenticate with her server, retrieve her roster (see <cite>RFC 3921</cite>), send initial presence to her server, and then receive presence information from all the contacts in her roster. If the presence information she receives from some contacts does not include capabilities data (per <cite>XEP-0115</cite>), Alice SHOULD then send a service discovery information ("disco#info") request to each of those contacts (in accordance with <cite>XEP-0030</cite>). Such initial service discovery stanzas MUST NOT be considered part of encrypted communication sessions for the purposes of this document, since they perform a "bootstrapping" function that is a prerequisite to encrypted communications. The disco#info request sent from Alice to Bob might look as follows:</p>
<example caption='Alice Queries Bob for ESession Support via Disco'><![CDATA[
<iq type='get'
from='alice@example.org/pda'
to='bob@example.com/laptop'
id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<p>If Bob sends a disco#info reply and he supports the protocol defined herein, then he MUST include a service discovery feature variable of "urn:xmpp:esession".</p>
<example caption='Bob Returns disco#info Data'><![CDATA[
<iq type='result'
from='bob@example.com/laptop'
to='alice@example.org/pda'
id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity category='client' type='pc'/>
...
<feature var='urn:xmpp:esession'/>
...
</query>
</iq>
]]></example>
</section1>
<section1 topic="Online ESession Negotiation" anchor='init'>
<section2 topic="Introduction" anchor='init-intro'>
<p>The process for establishing a secure session over an insecure transport is essentially a negotiation of various ESession algorithms and other parameters, combined with a translation into XMPP syntax of the &sigma; approach to key exchange (see <cite>Cryptographic Design of Encrypted Sessions</cite>).</p>
<p>If Alice believes Bob may be online then she SHOULD use the protocol specified in &xep0155; and in this section to negotiate the ESession options and the keys.</p>
<p>Note: If Alice believes Bob is offline then she SHOULD NOT use this negotiation protocol. However, she MAY use the protocol specified in <cite>Offline Encrypted Sessions</cite> to establish the ESession options and keys. Alternatively, she MAY send stanzas without encryption - in which case her client MUST make absolutely clear to her that the stanzas will not be protected and give her the option not to send the stanzas.</p>
</section2>
<section2 topic="Three- or Four-Message Negotiations" anchor='init-variants'>
<p>This protocol supports both 3- and 4-message key negotiations.</p>
<p>The 3-message SIGMA-I-based key exchange protects the identity of the <em>initiator</em> against active attacks. This SHOULD NOT be used to establish client-to-client sessions since the <em>responder's</em> identity is not protected against active attacks. However, it SHOULD be used to establish client-to-service (server) sessions, especially where the identity of the service is well known to third parties.</p>
<p>The 4-message SIGMA-R-based key exchange with hash commitment defends the <em>responder's</em> identity against active attacks and facilitates detection of a Man in the Middle attack. It SHOULD be used to establish client-to-client sessions. The 4-message key exchange also includes the following optional security enhancements:</p>
<ul>
<li><p>"Secret Retention": If retained secrets are employed <em>consistently</em> during key exchanges, then the Man in the Middle would need to be present for every session, including the first. Sessions remain secure even if a long-lived private signing key is compromised at some time <em>after</em> the first session.</p></li>
<li><p>"Short-Authentication-String": Alice and Bob can use SAS once to quickly authenticate each other's public keys. Only a very short human-friendly string needs to be verified out-of-band (e.g. by recognizable voice communication).</p>
<p>Alternatively, thanks to its protection against Man-in-the-Middle attacks, SAS can be used to eliminate the need to generate, distribute or authenticate any public keys. Note: When this protocol is being used without public keys Alice and Bob SHOULD employ Secret Retention, then the out-of-band verification only needs to be performed once to verify the absence of a Man in the Middle for all sessions (past, present and future). <note>This combination of techniques underpins the <cite>ZRTP</cite> key agreement protocol.</note></p></li>
<li><p>"Other Secret": Alice and Bob agree a password out-of-band and their clients use it to authenticate each other every time a session is negotiated.</p></li>
</ul>
</section2>
<section2 topic="ESession Request" anchor='init-online-request'>
<p>In addition to the "accept", "security", "otr" and "disclosure" fields (see <link url='#sec-backdoor'>Back Doors</link>) specified in <cite>Chat Session Negotiation</cite>, Alice MUST send to Bob each of the ESession options (see list below) that she is willing to use, in her order of preference (see <link url='#sec-mandatory'>Mandatory to Implement Technologies</link>).</p>
<ol>
<li><p>The list of Modular Exponential (MODP) group numbers (as specified in &rfc2409; or &rfc3526;) that MAY be used for Diffie-Hellman key exchange (valid group numbers include 1,2,3,4,5,14,15,16,17 and 18)</p></li>
<li><p>Symmetric block cipher algorithm names</p></li>
<li><p>Hash algorithm names</p></li>
<li><p>Signature algorithm names</p></li>
<li><p>Compression algorithm names</p></li>
<li><p>The list of stanza types that MAY be encrypted and decrypted</p></li>
<li><p>The different versions of this protocol that are supported <note>This version of this document describes version 1.0 of this protocol.</note></p></li>
<li><p>The minimum number of stanzas that MUST be exchanged before an entity MAY initiate a key re-exchange (1 - every stanza, 100 - every hundred stanzas). Note: This value MUST be less than &twosup32; (see <link url='#sec-rekey'>Re-Keying Limits</link>)</p></li>
<li><p>What sort of identification is required from the other entity. This MUST be either 'key' (its public signature-verification key), or 'hash' (a fingerprint of its public key) <note>If the entity already possesses one of the other entity's public keys then it is RECOMMENDED that only the fingerprint is requested from the other entity - since this saves bandwidth.</note>, or 'none' (no identification). 'none' MUST NOT be specified with 3-message negotiation.</p></li>
</ol>
<p>Each MODP group has at least two well known constants: a large prime number p, and a generator g for a subgroup of GF(p). For each MODP group that Alice specifies she MUST perform the following computations to calculate her Diffie-Hellman keys (where n is the number of bits per cipher block for the block cipher algorithm with the largest block size out of those she specified):</p>
<ol>
<li><p>Generate: a secret random number x (where &twosup2n; &lt; x &lt; p - 1)</p></li>
<li><p>Calculate: e = &gsupx; mod p</p></li>
<li><p>Calculate: He = SHA256(e) (see &nistfips180-2;)</p></li>
</ol>
<p>Note: The last step is not necessary for 3-message negotiations.</p>
<p>Alice MUST send all her calculated values of 'He' (for 4-message negotiations) or 'e' (for 3-message negotiations) to Bob (in the same order as the associated MODP groups are being sent). She MUST also specify randomly generated Base64 encoded (in accordance with Section 3 of &rfc3548;) value of &NsubA; (her ESession ID).</p>
<example caption='Initiates a 4-message ESession Negotiation'><![CDATA[
<message from='alice@example.org/pda' to='bob@example.com'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='form' xmlns='jabber:x:data'>
<field type="hidden" var="FORM_TYPE">
<value>urn:xmpp:chatneg</value>
</field>
<field type="boolean" var="accept">
<value>1</value>
<required/>
</field>
<field type="list-single" var="otr">
<option><value>false</value></option>
<option><value>true</value></option>
<required/>
</field>
<field type="list-single" var="disclosure">
<option><value>never</value></option>
<required/>
</field>
<field type="list-single" var="security">
<option><value>e2e</value></option>
<option><value>c2s</value></option>
<required/>
</field>
<field type="list-single" var="modp">
<option><value>5</value></option>
<option><value>14</value></option>
<option><value>2</value></option>
</field>
<field type="list-single" var="crypt_algs">
<option><value>aes256-ctr</value></option>
<option><value>twofish256-ctr</value></option>
<option><value>aes128-ctr</value></option>
</field>
<field type="list-single" var="hash_algs">
<option><value>whirlpool</value></option>
<option><value>sha256</value></option>
</field>
<field type="list-single" var="sign_algs">
<option><value>rsa</value></option>
<option><value>dsa</value></option>
</field>
<field type="list-single" var="compress">
<option><value>none</value></option>
</field>
<field type="list-multi" var="stanzas">
<option><value>message</value></option>
<option><value>iq</value></option>
<option><value>presence</value></option>
</field>
<field type="list-single" var="pubkey">
<value>key</value>
<option><value>key</value></option>
<option><value>hash</value></option>
<option><value>none</value></option>
</field>
<field type="list-single" var="ver">
<option><value>1.3</value></option>
<option><value>1.2</value></option>
</field>
<field type="text-single" var="rekey_freq">
<value>1</value>
</field>
<field type="hidden" var="my_nonce">
<value> ** Alice's Base64 encoded ESession ID ** </value>
</field>
<field type="hidden" var="dhhashes">
<value> ** Base64 encoded value of He5 ** </value>
<value> ** Base64 encoded value of He14 ** </value>
<value> ** Base64 encoded value of He2 ** </value>
</field>
</x>
</feature>
<amp xmlns='http://jabber.org/protocol/amp' per-hop='true'>
<rule action='drop' condition='deliver' value='stored'/>
</amp>
</message>
]]></example>
<p>The first message of a 3-message negotiation is identical except the a 'dhkeys' field is included instead of the 'dhhashes' field:</p>
<example caption='Alice Initiates a 3-message ESession Negotiation'><![CDATA[
<message from='alice@example.org/pda' to='bob@example.com'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='form' xmlns='jabber:x:data'>
<field type="hidden" var="FORM_TYPE">
<value>urn:xmpp:chatneg</value>
</field>
...
...
...
<field type="hidden" var="my_nonce">
<value> ** Alice's Base64 encoded ESession ID ** </value>
</field>
<field type="hidden" var="dhkeys">
<value> ** Base64 encoded value of e5 ** </value>
<value> ** Base64 encoded value of e14 ** </value>
<value> ** Base64 encoded value of e2 ** </value>
</field>
</x>
</feature>
<amp xmlns='http://jabber.org/protocol/amp' per-hop='true'>
<rule action='drop' condition='deliver' value='stored'/>
</amp>
</message>
]]></example>
<p>If Bob does not want to reveal presence to Alice for whatever reason then Bob SHOULD return no response or error.</p>
<p>If Bob supports <em>none</em> of the options for one or more ESession fields, then he SHOULD return a &notacceptable; error and SHOULD specify the field(s) with unsupported options in a comma-separated list in the XMPP &lt;text/&gt; element:</p>
<example caption='Bob Informs Alice that Her Options Are Not Supported'><![CDATA[
<message type='error'
from='bob@example.com/laptop'
to='alice@example.org/pda'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
...
</feature>
<error type='cancel'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>modp,ver</text>
</error>
</message>
]]></example>
<p>Either Bob or Alice MAY attempt to initiate a new ESession after any error during the negotiation process. However, both MUST consider the previous negotiation to have failed and MUST discard any information learned through the previous negotiation.</p>
<p>If Bob is unwilling to start an ESession, but he <em>is</em> ready to initiate a one-to-one chat session with Alice (see <cite>Chat Session Negotiation</cite>), and if Alice included an option for the "security" field with the value "none" or "c2s", then Bob SHOULD accept the Chat Session and terminate the ESession negotiation by specifying "none" or "c2s" for the value of the "security" field in his response.</p>
<example caption='Bob Accepts Chat Session'><![CDATA[
<message from='bob@example.com/laptop' to='alice@example.org/pda'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='submit' xmlns='jabber:x:data'>
<field var="FORM_TYPE">
<value>urn:xmpp:chatneg</value>
</field>
<field var="accept"><value>1</value></field>
<field var="otr"><value>true</value></field>
<field var="disclosure"><value>never</value></field>
<field var="security"><value>c2s</value></field>
</x>
</feature>
</message>
]]></example>
</section2>
<section2 topic="Diffie-Hellman Preparation (Bob)" anchor='init-online-bobprep'>
<p>If Bob supports one or more of each of Alice's ESession options and is willing to start an ESession with Alice, then he MUST select one of the options from each of the ESession fields he received from Alice including one hash algorithm ("HASH"), and one of the MODP groups (see &rfc3766; or <cite>RFC 3526</cite> for recommendations regarding balancing the sizes of symmetric cipher blocks and Diffie-Hellman moduli) and Alice's corresponding value of 'He' (for 4-message negotiations) or 'e' (for 3-message negotiations).</p>
<p>Note: Each MODP group has at least two well known constants: a large prime number p, and a generator g for a subgroup of GF(p).</p>
<p>For 3-message negotiations, Bob SHOULD return a &feature; error unless: 1 &lt; e &lt; p - 1</p>
<p>Bob MUST then perform the following computations (where n is the number of bits per cipher block for the selected block cipher algorithm):</p>
<ol start='1'>
<li><p>Generate a random number &NsubB; (his ESession ID)</p></li>
<li><p>Generate an n-bit random number &CsubA; (the block cipher counter for stanzas sent from Alice to Bob)</p></li>
<li><p>Set &CBeCAx2n1; (where &CsubB; is the block counter for stanzas sent from Bob to Alice)</p></li>
<li><p>Generate a secret random number y (where &twosup2n; &lt; y &lt; p - 1)</p></li>
<li><p>Calculate d = &gsupy; mod p</p></li>
<li><p>Calculate K = HASH(&esupy; mod p) (the shared secret)</p></li>
</ol>
<p>If this is a 4-message negotiation Bob MUST skip the last step above and all the steps described in the next two sections. He can skip straight to the <link url='#init-online-response'>ESession Response</link> section.</p>
</section2>
<section2 topic="Generating Session Keys" anchor='init-keys'>
<p>Bob MUST use HMAC with the selected hash algorithm ("HASH") and the shared secret ("K") to generate two sets of three keys, one set for each direction of the ESession.</p>
<p>For stanzas that Alice will send to Bob, the keys are calculated as:</p>
<ol>
<li><p>Encryption key &KCsubA; = <em>HMAC</em>(HASH, K, "Initiator Cipher Key")</p></li>
<li><p>Integrity key &KMsubA; = <em>HMAC</em>(HASH, K, "Initiator MAC Key")</p></li>
<!-- <note>&KMsubA; is a hash of &KCsubA; (not K) to ensure that if an attacker recovers the decryption key she will not be able to cryptographically convince anyone that it was not her who created the stanza.</note> -->
<li><p>SIGMA key &KSsubA; = <em>HMAC</em>(HASH, K, "Initiator SIGMA Key")</p></li>
</ol>
<p>For stanzas that Bob will send to Alice the keys are calculated as:</p>
<ol start='4'>
<li><p>Encryption key &KCsubB; = <em>HMAC</em>(HASH, K, "Responder Cipher Key")</p></li>
<li><p>Integrity key &KMsubB; = <em>HMAC</em>(HASH, K, "Responder MAC Key")</p></li>
<li><p>SIGMA key &KSsubB; = <em>HMAC</em>(HASH, K, "Responder SIGMA Key")</p></li>
</ol>
<p>Once the sets of keys have been calculated the value of K MUST be securely destroyed.</p>
<p>Note: As many bits of key data as are needed for each key MUST be taken from the least significant bits of the HMAC output. When negotiating a hash, entities MUST ensure that the hash output is no shorter than the required key data. For algorithms with variable-length keys the maximum length (up to the hash output length) SHOULD be used.</p>
</section2>
<section2 topic="Hiding Identity" anchor='init-hide'>
<p>Bob MUST perform the following steps before he can prove his identity to Alice while protecting it from third parties.</p>
<ol>
<li><p>If the value of the 'pubkey' field that Alice sent Bob was not 'none' then Bob MUST set &pubKeyB; to a zero length string of characters. Otherwise Bob SHOULD select &pubKeyB;, the public key Alice will use to authenticate his signature with the signature algorithm he selected ("SIGN").</p></li>
<li><p>Set &formB; to the <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the reponse data form he will send back to Alice (including his responses for all the fields he received from Alice) - see <link url='#init-online-response'>ESession Response</link>.</p>
<p>Bob MUST encapsulate the Base64 encoded values of &CsubA; and Alice's &NsubA; in two new 'counter' and 'nonce' fields and add them to &formB;. He MUST set the 'pubkey' field to specify what sort of identification he requires from Alice (see <link url='#init-online-request'>ESession Request</link>). He MUST set the value of the 'rekey_freq' field to be less than &twosup32; and greater than or equal to the value specified by Alice. Bob MUST place his Base64 encoded values of &NsubB; and d in the 'my_nonce' and 'dhkeys' fields. Note: Bob MUST NOT return Alice's values of &NsubA; and e in these fields.</p></li>
<li><p>Concatenate Alice's ESession ID, Bob's ESession ID, d, &pubKeyB; and &formB;, and calculate the HMAC (as defined in Section 2 of &rfc2104;) of the resulting byte string using the selected hash algorithm ("HASH") and the key &KSsubB;.</p>
<code>&macB; = <em>HMAC</em>(HASH, &KSsubB;, {&NsubA;, &NsubB;, d, &pubKeyB;, &formB;})</code></li>
<li><p>If the value of the 'pubkey' field that Alice sent Bob was not 'none' then Bob MUST calculate &signB;, the signature of the HMAC result using his private signature key that corresponds to &pubKeyB;</p>
<code>&signB; = SIGN(&signKeyB;, &macB;)</code></li>
<li><p>If the value of the 'pubkey' field that Alice sent Bob was 'hash' then Bob SHOULD set &pubKeyB; to the key's fingerprint</p>
<code>if (pubkey == 'hash') &pubKeyB; = HASH(&pubKeyB;)</code></li>
<li><p>Encrypt the byte string resulting from the concatenation of &pubKeyB; and &signB; (or, if the value of the 'pubkey' field that Alice sent Bob was 'none', encrypt just the HMAC result) with the agreed algorithm ("CIPHER") in counter mode (see &nistfips800-38a;), using the encryption key &KCsubB; and block counter &CsubB;. Note: &CsubB; MUST be incremented by 1 for each encrypted block or partial block (i.e. &CsubB; = (&CsubB; + 1) mod 2<span class='super'>n</span>, where n is the number of bits per cipher block for the agreed block cipher algorithm).</p>
<code>&IDB; = CIPHER(&KCsubB;, &CsubB;, {&pubKeyB;, &signB;})</code>
<p>or</p>
<code>&IDB; = CIPHER(&KCsubB;, &CsubB;, &macB;)</code></li>
<li><p>Calculate the HMAC of the encrypted identity (&IDB;) and the value of Bob's block cipher counter &CsubB;&#160;<em>before</em> the encryption above using the selected hash algorithm ("HASH") and the integrity key &KMsubB;.</p>
<code>&MsubB; = <em>HMAC</em>(HASH, &KMsubB;, &CsubB;, &IDB;)</code></li>
</ol>
</section2>
<section2 topic="ESession Response" anchor='init-online-response'>
<p>Bob responds to Alice by sending her &formB;.</p>
<example caption='Bob Responds to Alice (4-Message Negotiation)'><![CDATA[
<message from='bob@example.com/laptop' to='alice@example.org/pda'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='submit' xmlns='jabber:x:data'>
<field var="FORM_TYPE">
<value>urn:xmpp:chatneg</value>
</field>
<field var="accept"><value>1</value></field>
<field var="otr"><value>true</value></field>
<field var="disclosure"><value>never</value></field>
<field var="security"><value>e2e</value></field>
<field var="modp"><value>5</value></field>
<field var="crypt_algs"><value>aes256-ctr</value></field>
<field var="hash_algs"><value>sha256</value></field>
<field var="sign_algs"><value>rsa</value></field>
<field var="compress"><value>none</value></field>
<field var="stanzas"><value>message</value></field>
<field var="pubkey"><value>hash</value></field>
<field var="ver"><value>1.3</value></field>
<field var="rekey_freq"><value>50</value></field>
<field var="my_nonce">
<value> ** Bob's Base64 encoded ESession ID ** </value>
</field>
<field var="dhkeys">
<value> ** Base64 encoded value of d ** </value>
</field>
<field var="nonce">
<value> ** Alice's Base64 encoded ESession ID ** </value>
</field>
<field var="counter">
<value> ** Base64 encoded block counter ** </value>
</field>
</x>
</feature>
</message>
]]></example>
<p>If Bob prefers the RECOMMENDED 3-message ESession negotiation, where Alice's identity is protected from active attacks instead of his own, then he should encapsulate the Base64 encoded values of &IDB; and &MsubB; in data form fields ('identity' and 'mac'), and append the new fields to &formB; before sending it to Alice.</p>
<example caption='Bob Responds to Alice (3-Message Negotiation)'><![CDATA[
<message from='bob@example.com/laptop' to='alice@example.org/pda'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='submit' xmlns='jabber:x:data'>
<field var="FORM_TYPE">
<value>urn:xmpp:chatneg</value>
</field>
<field var="accept"><value>1</value></field>
<field var="otr"><value>true</value></field>
<field var="disclosure"><value>never</value></field>
<field var="security"><value>e2e</value></field>
<field var="modp"><value>5</value></field>
<field var="crypt_algs"><value>aes256-ctr</value></field>
<field var="hash_algs"><value>sha256</value></field>
<field var="sign_algs"><value>rsa</value></field>
<field var="compress"><value>none</value></field>
<field var="stanzas"><value>message</value></field>
<field var="pubkey"><value>hash</value></field>
<field var="ver"><value>1.3</value></field>
<field var="rekey_freq"><value>50</value></field>
<field var="my_nonce">
<value> ** Bob's Base64 encoded ESession ID ** </value>
</field>
<field var="dhkeys">
<value> ** Base64 encoded value of d ** </value>
</field>
<field var="nonce">
<value> ** Alice's Base64 encoded ESession ID ** </value>
</field>
<field var="counter">
<value> ** Base64 encoded block counter ** </value>
</field>
<field var="identity">
<value> ** Encrypted identity ** </value>
</field>
<field var="mac">
<value> ** Integrity of identity ** </value>
</field>
</x>
</feature>
</message>
]]></example>
</section2>
<section2 topic="Diffie-Hellman Preparation (Alice)" anchor='init-online-aliceprep'>
<p>After Alice receives Bob's response, she MUST use the value of d and the ESession options specified in Bob's response to perform the following steps (where p and g are the constants associated with the selected MODP group, HASH is the selected hash algorithm, and n is the number of bits per cipher block for the agreed block cipher algorithm):</p>
<ol start='1'>
<li><p>Return a &feature; error to Bob if she is not prepared to support any of the ESession options specified by Bob (if any of the options were not included in her initial ESession request)</p></li>
<li><p>Return a &feature; error to Bob unless: 1 &lt; d &lt; p - 1</p></li>
<li><p>Set &CBeCAx2n1; (where &CsubB; is the block counter for stanzas sent from Bob to Alice)</p></li>
<li><p>Select her values of x and e that correspond to the selected MODP group (from all the values of x and e she calculated previously)</p></li>
<li><p>Calculate K = HASH(&dsupx; mod p) (the shared secret)</p></li>
<li><p>Generate the session keys (&KCsubA;, &KMsubA;, &KSsubA;, &KCsubB;, &KMsubB; and &KSsubB;) in the same way as Bob did (see <link url='#init-keys'>Generating Session Keys</link>)</p></li>
</ol>
</section2>
<section2 topic="Verifying Bob's Identity" anchor='init-online-bobid'>
<p>If Bob included 'identity' and 'mac' fields in his response then Alice MUST also perform the following steps:</p>
<ol start='1'>
<li><p>Calculate the HMAC of the encrypted identity (&IDB;) and the value of Bob's block cipher counter using HASH and the integrity key &KMsubB;.</p>
<code>&MsubB; = <em>HMAC</em>(HASH, &KMsubB;, &CsubB;, &IDB;)</code></li>
<li><p>Return a &feature; error to Bob unless the value of &MsubB; she calculated matches the one she received in the 'mac' field</p></li>
<li><p>Obtain &pubKeyB; and &signB; by decrypting &IDB; with the agreed symmetric block cipher algorithm ("DECIPHER") in counter mode, using the encryption key &KCsubB; and block counter &CsubB;. Note: &CsubB; MUST be incremented by 1 for each encrypted block or partial block (i.e. &CsubB; = (&CsubB; + 1) mod 2<span class='super'>n</span>, where n is the number of bits per cipher block for the agreed block cipher algorithm).</p>
<code>{&pubKeyB;, &signB;} = DECIPHER(&KCsubB;, &CsubB;, &IDB;)</code></li>
<li><p>If the value of the 'pubkey' field she sent to Bob in her <link url='#init-online-request'>ESession Request</link> was 'hash', then Alice SHOULD change the value of &pubKeyB; to be her copy of the public key whose HASH matches the value of &pubKeyB; that she received from Bob. Note: If she cannot find a copy of the public key then Alice MUST terminate the ESession. She MAY then request a new ESession with the 'pubkey' field set to 'key' or 'none'.</p></li>
<li><p>Return a &feature; error to Bob unless she can confirm (or has previously confirmed) that &pubKeyB; really is Bob's public key, for examples, via secure out-of-band communication, or through a third-party authority (see <link url='#sec-keys'>Verifying Keys</link>).</p></li>
<li><p>Set the value of &formB; to be the <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the form she received from Bob without any 'identity' or 'mac' fields.</p></li>
<li><p>Concatenate Alice's ESession ID, Bob's ESession ID, d, &pubKeyB; and &formB;, and calculate the HMAC of the resulting byte string using HASH and the key &KSsubB;.</p>
<code>&macB; = <em>HMAC</em>(HASH, &KSsubB;, {&NsubA;, &NsubB;, d, &pubKeyB;, &formB;})</code></li>
<li><p>Return a &feature; error to Bob unless she can use &pubKeyB; with the selected signature verification algorithm ("VERIFY") to confirm that &signB; is the signature of the HMAC result (see <link url='#sign'>Signature Verification</link>).</p>
<code>VERIFY(&signB;, &pubKeyB;, &macB;)</code></li>
</ol>
</section2>
<section2 topic="ESession Completion" anchor='init-online-complete'>
<p>Alice MUST then prove her identity to Bob while protecting it from third parties. She MUST perform the steps equivalent to those Bob performed above (see <link url='#init-hide'>Hiding Identity</link> for a more detailed description). Alice's calculations are summarised below (pay attention to the order of &NsubB; and &NsubA; when calculating &macA;). Note: &formA; is the <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the <link url='#init-online-request'>ESession Request</link> data form that she sent to Bob previously.</p>
<code>&macA; = <em>HMAC</em>(HASH, &KSsubA;, {&NsubB;, &NsubA;, e, &pubKeyA;, &formA;})</code>
<code>&signA; = SIGN(&signKeyA;, &macA;)</code>
<code>if (pubkey == 'hash') &pubKeyA; = HASH(&pubKeyA;)</code>
<code>&IDA; = CIPHER(&KCsubA;, &CsubA;, {&pubKeyA;, &signA;})</code>
<code>&MsubA; = <em>HMAC</em>(HASH, &KMsubA;, &CsubA;, &IDA;)</code>
<p>Alice MUST send the Base64 encoded values of &NsubB;, &IDA; and &MsubA; to Bob. If Alice has already confirmed Bob's identity (i.e. if Bob included 'identity' and 'mac' fields in his response), then she MAY also send encrypted content (see &xep0200;) in the same stanza as the proof of her identity.</p>
<example caption='Alice Sends Bob Her Identity'><![CDATA[
<message from='alice@example.org/pda' to='bob@example.com/laptop'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='result' xmlns='jabber:x:data'>
<field var="FORM_TYPE"><value>urn:xmpp:chatneg</value></field>
<field var="accept"><value>1</value></field>
<field var="nonce"><value> ** Bob's Base64 encoded ESession ID ** </value></field>
<field var="identity"><value> ** Encrypted identity ** </value></field>
<field var="mac"><value> ** Integrity of identity ** </value></field>
</x>
</feature>
<c xmlns='urn:xmpp:crypt'>
<data> ** Base64 encoded m_final ** </data>
<mac> ** Base64 encoded a_mac ** </mac>
</c>
</message>
]]></example>
<p>If Alice also includes a 'terminate' field with its value set to "1" or "true" (see <link url='#terminate'>ESession Termination</link>) within the form then the ESession is terminated immediately. Note: This special case, where a single stanza is encrypted and sent in isolation, is equivalent to object encryption (or object signing if no encryption is specified) and offers several significant advantages over non-session approaches - including perfect forward secrecy.</p>
<p>After receiving Alice's identity Bob MUST verify it by performing steps equivalent to those described in the section <link url='#init-online-bobid'>Verifying Bob's Identity</link> above. Some of Bob's calculations are summarised below (pay attention to the order of &NsubB; and &NsubA; when calculating &macA;). Note: &formA; is the <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the <link url='#init-online-request'>ESession Request</link> data form (the <em>first</em> form) that Alice sent him. Note: If Bob sends an error to Alice then he SHOULD ignore any encrypted content he received in the stanza.</p>
<code>&MsubA; = <em>HMAC</em>(HASH, &KMsubA;, &CsubA;, &IDA;)</code>
<code>{&pubKeyA;, &signA;} = DECIPHER(&KCsubA;, &CsubA;, &IDA;)</code>
<code>&macA; = <em>HMAC</em>(HASH, &KSsubA;, {&NsubB;, &NsubA;, e, &pubKeyA;, &formA;})</code>
<code>VERIFY(&signA;, &pubKeyA;, &macA;)</code>
<p>If Alice has already confirmed Bob's identity (i.e. if Bob included 'identity' and 'mac' fields in his response above), then the ESession negotiation is complete.</p>
<p>Otherwise, one more step is necessary. Bob MUST send Alice the Base64 encoded values of &NsubA;, &IDB; and &MsubB; that he calculated previously (see <link url='#init-hide'>Hiding Identity</link>). Note: He MAY also send encrypted content (see <cite>Stanza Encryption</cite>) in the same stanza.</p>
<example caption='Bob Sends Alice His Identity'><![CDATA[
<message from='bob@example.com/laptop' to='alice@example.org/pda'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<init xmlns='urn:xmpp:esession#init'>
<x type='result' xmlns='jabber:x:data'>
<field var="FORM_TYPE"><value>urn:xmpp:chatneg</value></field>
<field var="nonce"><value> ** Alice's Base64 encoded ESession ID ** </value></field>
<field var="identity"><value> ** Encrypted identity ** </value></field>
<field var="mac"><value> ** Integrity of identity ** </value></field>
</x>
</init>
</message>
]]></example>
<p>After receiving Bob's identity Alice MUST verify it by performing steps described in the section <link url='#init-online-bobid'>Verifying Bob's Identity</link> above. Note: If Alice sends an error to Bob then she SHOULD ignore any encrypted content she received in the stanza.</p>
<p>Once ESession negotiation is complete, Alice and Bob MUST exchange only encrypted forms of the one-to-one stanza types they agreed upon (e.g., &MESSAGE; and &IQ; stanzas).</p>
</section2>
</section1>
<section1 topic='ESession Termination' anchor='terminate'>
<p>Either entity MAY terminate an ESession at any time. Entities MUST terminate all open ESessions before they go offline. To terminate an ESession Alice MUST send an encrypted stanza to Bob including within the encrypted XML of the &lt;data/&gt; element a chat negotiation form with a "terminate" field (as specified in the Termination section of <cite>Chat Session Negotiation</cite>). Note: She MAY publish old values of &KMsubA; and/or &KMsubB; within her termination stanza as long as she is sure all the stanzas that MAY use the old values have been received and validated (see <cite>Stanza Encryption</cite>). She MUST then securely destroy all keys associated with the ESession.</p>
<example caption='Alice Terminates an ESession'><![CDATA[
<message from='alice@example.org/pda' to='bob@example.com/laptop'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<c xmlns='urn:xmpp:crypt'>
<data> ** Base64 encoded encrypted terminate form ** </data>
<old> ** Base64 encoded old MAC key ** </old>
<mac> ** Base64 encoded a_mac ** </mac>
</c>
</message>
]]></example>
<p>When Bob receives a termination stanza he MUST verify the MAC (to be sure he received all the stanzas Alice sent him during the ESession) and immediately send an encrypted termination acknowledgement form (as specified in the Termination section of <cite>Chat Session Negotiation</cite>) back to Alice. Note: He MAY publish <em>any</em> old values of &KMsubA; or &KMsubB; within the acknowledgement stanza. He MUST then securely destroy all keys associated with the ESession.</p>
<example caption='Bob Acknowledges ESession Termination'><![CDATA[
<message from='bob@example.com/laptop' to='alice@example.org/pda'>
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<c xmlns='urn:xmpp:crypt'>
<data> ** Base64 encoded encrypted acknowledgement form ** </data>
<old> ** Base64 encoded old MAC key ** </old>
<mac> ** Base64 encoded b_mac ** </mac>
</c>
</message>
]]></example>
<p>When Alice receives the stanza she MUST verify the MAC to be sure she received all the stanzas Bob sent her during the ESession. Once an entity has sent a termination or termination acknowledgement stanza it MUST NOT send another stanza within the ESession.</p>
</section1>
<section1 topic='Signature Generation and Verification' anchor='sign'>
<section2 topic='XML Normalization' anchor='sign-normal'>
<p>Before the signature or MAC of a block of XML is generated or verified, all character data <em>between</em> all elements MUST be removed and the XML MUST be converted to canonical form (see &w3canon;).</p>
<p>All the XML this protocol requires to be signed or MACed is very simple, so in this case, canonicalization SHOULD only require the following changes:</p>
<ul>
<li>Set attribute value delimiters to single quotation marks (i.e. simply replace all single quotes in the serialized XML with double quotes)</li>
<li>Impose lexicographic order on the attributes of "field" elements (i.e. ensure "type" is before "var")</li>
</ul>
<p>Implementations MAY conceivably also need to make the following changes. Note: Empty elements and special characters SHOULD NOT appear in the signed or MACed XML specified in this protocol.</p>
<ul>
<li>Ensure there are no character references</li>
<li>Convert empty elements to start-end tag pairs</li>
<li>Ensure there is no whitespace except for single spaces before attributes</li>
</ul>
</section2>
<section2 topic='Hash' anchor='sign-hash'>
<p>Before the signature or MAC of a block of XML is generated or verified, the agreed hash algorithm MUST be used to generate the hash of the normalized XML.</p>
<code>m_hash = HASH(m_content)</code>
</section2>
<section2 topic='Generation' anchor='sign-calc'>
<p>The signature generation depends on the type of private key being used.</p>
<section3 topic='RSA' anchor='sign-rsa-gen'>
<code>signature_rsa = rsa_sign(rsa_private_key, m_hash, hashOID)</code>
<p>The multiprecision integer signature_rsa is the signature (see &rfc3447;).</p>
</section3>
<section3 topic='DSA' anchor='sign-dsa-gen'>
<code>sig_dsa_r, sig_dsa_s = dsa_sign(dsa_private_key, m_hash)</code>
<p>The multiprecision integers sig_dsa_r and sig_dsa_s are the signature (see &nistfips186-2;).</p>
</section3>
</section2>
<section2 topic='Signature Format' anchor='sign-format'>
<p>The signature formats are the same for all public key formats. All integers are stored in big-endian byte order.</p>
<section3 topic='RSA' anchor='sign-rsa-format'>
<p>Base64 encoding of the signature_rsa multiprecision integer (without any header or length prefix).</p>
</section3>
<section3 topic='DSA' anchor='sign-dsa-format'>
<p>Base64 encoding of the following structure:</p>
<ul>
<li>number of bytes in sig_dsa_r (2-byte integer)</li>
<li>sig_dsa_r</li>
<li>number of bytes in sig_dsa_s (2-byte integer)</li>
<li>sig_dsa_s</li>
</ul>
</section3>
</section2>
<section2 topic='Verification' anchor='sign-calc'>
<p>The signature verification depends on the type of public key being used.</p>
<section3 topic='RSA' anchor='sign-rsa-verify'>
<p>The rsa_modulus and rsa_public_exponent multiprecision integers are extracted from the other entity's authenticated public key. The signature_rsa multiprecision integer is the signature received from the other entity.</p>
<code>boolean = rsa_verify(signature_rsa, m_hash, hashOID, rsa_modulus, rsa_public_exponent)</code>
</section3>
<section3 topic='DSA' anchor='sign-dsa-verify'>
<p>The dsa_p, dsa_q, dsa_g and dsa_y multiprecision integers are extracted from the other entity's authenticated public key. The sig_dsa_r and sig_dsa_s multiprecision integers are the signature received from the other entity.</p>
<code>boolean = dsa_verify(sig_dsa_r, sig_dsa_s, m_hash, dsa_p, dsa_q, dsa_g, dsa_y)</code>
</section3>
</section2>
</section1>
<section1 topic='Security Considerations' anchor='sec'>
<section2 topic='Random Numbers' anchor='sec-prng'>
<p>Weak pseudo-random number generators (PRNG) enable successful attacks. Implementors MUST use a cryptographically strong PRNG to generate all random numbers (see &rfc1750;).</p>
</section2>
<section2 topic='Replay Attacks' anchor='sec-replay'>
<p>Alice and Bob MUST ensure that the value of e or d they provide when negotiating each online ESession is unique. This prevents complete online ESessions being replayed.</p>
</section2>
<section2 topic='Verifying Keys' anchor='sec-keys'>
<p>The trust system outlined in this document is based on Alice trusting that the public key presented by Bob is <em>actually</em> Bob's key (and vice versa). Determining this trust may be done in a variety of ways depending on the entities' support for different public key (certificate) formats, signing algorithms and signing authorities. For instance, if Bob publishes a PGP/GPG public key, Alice MAY verify that his key is signed by another key that she knows to be good. Or, if Bob provides an X.509 certificate, she MAY check that his key has been signed by a Certificate Authority that she trusts.</p>
<p>When trust cannot be achieved automatically, methods that are not transparent to the users may be employed. The out-of-band Short Authentication String mechanism described in this document is an easy way for people to do that. Alternatively, Bob could communicate the <em>full</em> SHA-256 fingerprint of his public key to Alice via secure out-of-band communication (e.g. face-to-face). This would enable Alice to confirm that the public key she receives in-band is valid. Note: Since very few people bother to (consistently) verify SAS or fingerprints, entities SHOULD protect against 'man-in-the-middle' attacks using retained secrets and/or other secrets.</p>
<p>Note: If no keys are acceptable to Alice (because Alice has never verified any of the keys, and because either the keys are not signed, or Alice does not support the signature algorithms of the keys, or she cannot parse the certificate formats, or she does not recognise the authorities that signed the keys) then, although the ESession can still be encrypted, she cannot be sure she is communicating with Bob.</p>
</section2>
<section2 topic='Key Associations' anchor='sec-associations'>
<p>An entity SHOULD remember the fingerprints of all public keys it receives, and remember whether or not they have been validated by the user (see <link url='#sec-keys'>Verifying Keys</link>).</p>
<p>Entities MUST associate one or more JIDs with each public key fingerprint that they store, and alert their users immediately if another JID presents the same public key. This is necessary since if Bob already has fingerprints from Alice and Mallory, and Bob's client presents only the JID (or a name associated with the JID) to Bob, then Mallory could use his own public key (that is trusted by Bob) and pretend to be Alice simply by exchanging stanzas with Bob using Alice's JID.</p>
<p>If a JID for which a key has previously been stored attempts to establish an ESession using a public key with a different fingerprint (or no key at all) then the entity MUST alert its user.</p>
<p>Since Alice MAY use many different JIDs to talk to Bob, but always identify herself to him with the same public key, Entities SHOULD associate a "petname" with each public key fingerprint they store. Entities MUST present any public key petnames clearly to their users, and more prominently than any petname or nickname associated with the JID or the JID itself.</p>
</section2>
<section2 topic='Unencrypted ESessions' anchor='sec-unencrypted'>
<p>Organisations with full disclosure policies may require entities to disable encryption (see <link url='#sec-backdoor'>Back Doors</link>) to enable the logging of all messages on their server. Unencrypted ESessions meet all the Security Requirements (see <cite>Cryptographic Design of Encrypted Sessions</cite>) except for Confidentiality. Unencrypted ESessions enable Alice to to confirm <em>securely</em> with Bob that both client-server connections are secure. i.e. that the value of the 'security' option (as specified in <cite>Chat Session Negotiation</cite>) has not been tampered with.</p>
</section2>
<section2 topic="Back Doors" anchor="sec-backdoor">
<p>The authors and the XSF would like to discourage the deliberate inclusion of "back doors" in implementations of this protocol. However, we recognize that some organizations must monitor chats or record chats in decryptable form for legal compliance reasons, or may choose to monitor chats for quality assurance purposes. In these cases it is important to inform the other entity of the (potential for) disclosure before starting the ESession (if only to maintain public confidence in this protocol).</p>
<p>Both implementations MUST immediately and clearly inform their users if the negotiated value of the 'disclose' field is not 'never'.</p>
<p>Before disclosing any chat, an entity SHOULD either negotiate the value of the 'disclose' field to be 'enabled' or terminate the negotiation unsuccessfully. It MUST NOT negotiate the value of the 'disclose' field to be 'disabled' unless it would be illegal for it to divulge the disclosure to the other entity.</p>
<p>In any case an implementation MUST NOT negotiate the value of the 'disclose' field to be 'never' unless it implements no feature or mechanism (not even a disabled feature or mechanism) that could be used directly or indirectly to divulge to <em>any</em> third-party either the identites of the participants, or the keys, or the content of <em>any</em> ESession (or information that could be used to recover any of those items). If an implementation deliberately fails to observe this last point (or fails to correct an accidental back door) then it is not compliant with this protocol and MUST NOT either claim or imply any compliance with this protocol or any of the other protocols developed by the authors or the XSF. In this case the authors and the XSF reserve all rights regarding the names of the protocols.</p>
<p>The expectation is that this legal requirement will persuade many implementors either to tell the users of their products that a back door exists, or not to implement a back door at all (if, once informed, the market demands that).</p>
</section2>
<section2 topic='Extra Responsabilities of Implementors' anchor='sec-general'>
<p>Cryptography plays only a small part in an entity's security. Even if it implements this protocol perfectly it may still be vulnerable to other attacks. For examples, an implementation might store ESession keys on swap space or save private keys to a file in cleartext! Implementors MUST take very great care when developing applications with secure technologies.</p>
</section2>
<section2 topic='Mandatory to Implement Technologies' anchor='sec-mandatory'>
<p>An implementation of ESession MUST support the Diffie-Hellman Key Agreement and HMAC algorithms. Note: The parameter names mentioned below are related to secure shell; see <cite>SSH Transport Layer Encryption Modes</cite> for block cipher algorithm details; see the &ianassh; for other names.</p>
<section3 topic='Block Cipher Algorithms' anchor='sec-mandatory-encryption'>
<p>An implementation of ESession MUST support at least the following block cipher algorithm:</p>
<ul>
<li>aes128-ctr (see &nistfips197;)</li>
</ul>
<p>The block length of an block cipher algorithm's cipher SHOULD be at least 128 bits. An implementation of ESession MAY also support the following block cipher algorithms:</p>
<ul>
<li>aes256-ctr</li>
<li>aes192-ctr</li>
<li>twofish256-ctr (see &twofish;)</li>
<li>twofish192-ctr</li>
<li>twofish128-ctr</li>
<li>serpent256-ctr (see &serpent;)</li>
<li>serpent192-ctr</li>
<li>serpent128-ctr</li>
<li>none (no encryption, only signing)</li>
</ul>
</section3>
<section3 topic='Key Signing Algorithms' anchor='sec-mandatory-sign'>
<p>An implementation of ESession MUST support at least the following signing algorithm:</p>
<ul>
<li>rsa (see <cite>RFC 3447</cite>)</li>
</ul>
<p>An implementation of ESession SHOULD also support at least the following signing algorithm:</p>
<ul>
<li>dsa (see <cite>Digital Signature Standard</cite>)</li>
</ul>
</section3>
<section3 topic='Public Signature-Verification-Key Formats' anchor='sec-mandatory-public'>
<p>An implementation of ESession MUST support the following public key formats:</p>
<ul>
<li>ssh-rsa</li>
</ul>
<p>An implementation of ESession SHOULD also support at least the following public key formats:</p>
<ul>
<li>ssh-dss</li>
<li>x509v3-sign-rsa (see &sshx509;)</li>
<li>x509v3-sign-dss</li>
<li>pgp-sign-rsa</li>
<li>pgp-sign-dss</li>
</ul>
<p>An implementation of ESession MAY also support the following public key formats:</p>
<ul>
<li>spki-sign-rsa</li>
<li>spki-sign-dss</li>
</ul>
</section3>
<section3 topic='Hash Algorithms' anchor='sec-mandatory-hash'>
<p>An implementation of ESession MUST support the following hash algorithm:</p>
<ul>
<li>sha256 (see <cite>Secure Hash Standard</cite>)</li>
</ul>
<p>An implementation of ESession SHOULD also support at least the following hash algorithm (sha1 and md5 are broken and therefore NOT RECOMMENDED):</p>
<ul>
<li>whirlpool (see &whirlpool;)</li>
</ul>
</section3>
<section3 topic='Compression Algorithms' anchor='sec-mandatory-compress'>
<p>An implementation of ESession MUST support the following compression algorithm:</p>
<ul>
<li>none (no compression, the output MUST be the same as the input)</li>
</ul>
<p>Support for other algorithms is NOT RECOMMENDED since compression partially defeats the <link url='#reqs-repudiate'>Repudiability</link> requirement of this document by making it more difficult for a third party (with some knowledge of the plaintext) to modify a transcript of an encrypted session in a meaningful way. However, encrypted content is pseudo-random and cannot be compressed, so, in those cases where bandwidth is severely constrained, an implementation of ESession MAY support the following algorithms to compress content before it is encrypted:</p>
<ul>
<li>lzw (see &ecma151;)</li>
<li>zlib (see &rfc1950;)</li>
</ul>
</section3>
</section2>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with &IANA;. </p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Namespaces' anchor='registrar-ns'>
<p>Upon approval of this document, the &REGISTRAR; shall register the following namespaces:</p>
<ul>
<li>urn:xmpp:esession</li>
<li>urn:xmpp:esession#init</li>
</ul>
</section2>
<section2 topic='Field Standardization' anchor='registrar-formtype'>
<p>&xep0068; defines a process for standardizing the fields used within Data Forms qualified by a particular namespace. The following fields shall be registered for use in <em>both</em> Encrypted Session Negotiation and Chat Session Negotiation:</p>
<code caption='Registry Submission'><![CDATA[
<form_type>
<name>urn:xmpp:esession</name>
<jep>XEP-0116</jep>
<desc>ESession negotiation forms</desc>
<field
var='compress'
type='list-single'
label='Compression algorithm options'/>
<field
var='counter'
type='hidden'
label='Initial block counter'/>
<field
var='crypt_algs'
type='list-single'
label='Symmetric block cipher options'/>
<field
var='dhhashes'
type='hidden'
label='Hashes of Diffie-Hellman public keys'/>
<field
var='dhkeys'
type='hidden'
label='Diffie-Hellman public keys'/>
<field
var='expires'
type='hidden'
label='Expiry time of offline ESession options'/>
<field
var='hash_algs'
type='list-single'
label='Hash algorithm options'/>
<field
var='match_resource'
type='text-single'
label='Target resource for offline ESessions'/>
<field
var='modp'
type='list-single'
label='MODP group number'/>
<field
var='my_nonce'