0.16 RC1 init_pubkey and resp_pubkey fields

git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@874 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Ian Paterson 2007-05-30 14:15:14 +00:00
parent 5891a7d520
commit 2a64a3e9ed
1 changed files with 149 additions and 124 deletions

View File

@ -31,16 +31,10 @@
<!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>
@ -65,6 +59,7 @@
<spec>XEP-0020</spec>
<spec>XEP-0030</spec>
<spec>XEP-0068</spec>
<spec>XEP-0115</spec>
<spec>XEP-0155</spec>
<spec>XEP-0200</spec>
</dependencies>
@ -74,6 +69,12 @@
&ianpaterson;
&stpeter;
&dizzyd;
<revision>
<version>0.16</version>
<date>2007-05-30</date>
<initials>ip</initials>
<remark><p>Split pubkey field into init_pubkey and resp_pubkey fields</p></remark>
</revision>
<revision>
<version>0.15</version>
<date>2007-03-16</date>
@ -167,9 +168,10 @@
</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 &xep0210; and <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>
<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 (see &rfc3920; and &rfc3921;), 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 &xep0210;, 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>Requirements for Encrypted Sessions</cite> and &xep0188;. 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>
<p>&xep0217; describes a minimal subset of this protocol chosen to enable developers to produce working code before they have finished implementing the optional parts of this protocol.</p>
</section1>
<section1 topic="Dramatis Personae" anchor='personae'>
@ -213,7 +215,7 @@
<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>
<p>Note: If Alice believes Bob is offline then she SHOULD NOT use this negotiation protocol. However, she MAY use the protocol specified in &xep0187; 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 Negotiation?" anchor='init-variants'>
@ -229,102 +231,109 @@
</section2>
<section2 topic="ESession Request (Alice)" 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>Stanza 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>
<p>In addition to the "accept", "security", "otr" and "disclosure" fields (see <link url='#sec-backdoor'>Back Doors</link>) specified in <cite>Stanza Session Negotiation</cite>, Alice MUST send to Bob each of the ESession options (see list below) that she is willing to use (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>Short Authentication String generation 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 wrapped in a &lt;KeyValue/&gt; element as specified in &w3xmlsig;), or 'hash' (a fingerprint of the public key - the result of processing the <link url='#sign-normal'>Normalized</link> &lt;KeyValue/&gt; element with the selected hash algorithm, "HASH") <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 authentication via public keys). Note: 'none' MUST NOT be specified with 3-message negotiation.</p></li>
<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 in a "modp" field (valid group numbers include 1,2,3,4,5,14,15,16,17 and 18) <note>Entities SHOULD offer even the lowest MODP groups since some entities are CPU-constrained, and security experts tend to agree that "longer keys do not protect against the most realistic security threats".</note></p></li>
<li><p>Symmetric block cipher algorithm names in a "crypt_algs" field</p></li>
<li><p>Hash algorithm names in a "hash_algs" field</p></li>
<li><p>Compression algorithm names in a "compress" field</p></li>
<li><p>Short Authentication String generation algorithm names in a "sas_algs" field</p></li>
<li><p>The list of stanza types that MAY be encrypted and decrypted in a "stanzas" field (message, presence, iq)</p></li>
<li><p>The different versions of this protocol that are supported in a "ver" field <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 in a "rekey_freq" field (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>The methods of identification of the other entity that would be acceptable, and the methods of identification that this entity is prepared to offer ("init_pubkey" and "resp_pubkey" parameters). The values of these two parameters MUST be either 'key' (a public signature-verification key wrapped in a &lt;KeyValue/&gt; element as specified in &w3xmlsig;), or 'hash' (a fingerprint of the public key - the result of processing the <link url='#sign-normal'>Normalized</link> &lt;KeyValue/&gt; element with the selected hash algorithm, "HASH") <note>If the entity already possesses one of the other entity's public keys then it is RECOMMENDED that the fingerprint is requested from the other entity instead of the public key - since this saves bandwidth.</note>, or 'none' (no authentication via public keys). Note: 'none' MUST NOT be specified with 3-message negotiation.</p></li>
<li><p>Signature algorithm names (unless the values of the "init_pubkey" and "resp_pubkey" parameters are fixed to 'none')</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>
<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 <em>each</em> 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 4 of &rfc4648;) value of &NsubA; (her ESession ID).</p>
<p>Alice MUST send all her calculated values of 'He' (for 4-message negotiations) or 'e' (for 3-message negotiations) to Bob (in a "dhhashes" field in the same order as the associated MODP groups are being sent) Base64 encoded (in accordance with Section 4 of &rfc4648;). She MUST also specify a randomly generated Base64 encoded value of &NsubA; (her ESession ID in a "my_nonce" field).</p>
<p>The options in each field MUST appear in Alice's order of preference.</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">
<field type='hidden' var='FORM_TYPE'>
<value>urn:xmpp:ssn</value>
</field>
<field type="boolean" var="accept">
<field type='boolean' var='accept'>
<value>1</value>
<required/>
</field>
<field type="list-single" var="otr">
<field type='list-single' var='otr'>
<option><value>false</value></option>
<option><value>true</value></option>
<required/>
</field>
<field type="list-single" var="disclosure">
<field type='list-single' var='disclosure'>
<option><value>never</value></option>
<required/>
</field>
<field type="list-single" var="security">
<field type='list-single' var='security'>
<option><value>e2e</value></option>
<option><value>c2s</value></option>
<required/>
</field>
<field type="list-single" var="modp">
<field type='list-single' var='modp'>
<option><value>5</value></option>
<option><value>14</value></option>
<option><value>2</value></option>
<option><value>1</value></option>
</field>
<field type="list-single" var="crypt_algs">
<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">
<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">
<field type='list-single' var='sign_algs'>
<option><value>http://www.w3.org/2000/09/xmldsig#rsa-sha256</value></option>
<option><value>http://www.w3.org/2000/09/xmldsig#dsa-sha256</value></option>
</field>
<field type="list-single" var="compress">
<field type='list-single' var='compress'>
<option><value>none</value></option>
</field>
<field type="list-multi" var="stanzas">
<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>
<field type='list-single' var='init_pubkey'>
<option><value>key</value></option>
<option><value>hash</value></option>
<option><value>none</value></option>
</field>
<field type="list-single" var="ver">
<field type='list-single' var='resp_pubkey'>
<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">
<field type='text-single' var='rekey_freq'>
<value>1</value>
</field>
<field type="hidden" var="my_nonce">
<field type='hidden' var='my_nonce'>
<value> ** Alice's Base64 encoded ESession ID ** </value>
</field>
<field type="list-single" var="sas_algs">
<field type='list-single' var='sas_algs'>
<option><value>sas28x5</value></option>
</field>
<field type="hidden" var="dhhashes">
<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>
<value> ** Base64 encoded value of He1 ** </value>
</field>
</x>
</feature>
@ -339,16 +348,16 @@
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='form' xmlns='jabber:x:data'>
<field type="hidden" var="FORM_TYPE">
<field type='hidden' var='FORM_TYPE'>
<value>urn:xmpp:ssn</value>
</field>
...
...
...
<field type="hidden" var="my_nonce">
<field type='hidden' var='my_nonce'>
<value> ** Alice's Base64 encoded ESession ID ** </value>
</field>
<field type="hidden" var="dhkeys">
<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>
@ -406,13 +415,13 @@
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='submit' xmlns='jabber:x:data'>
<field var="FORM_TYPE">
<field var='FORM_TYPE'>
<value>urn:xmpp:ssn</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>
<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>
@ -439,7 +448,7 @@
<section3 topic="Response Form" anchor='init-online-form'>
<p>Bob SHOULD generate the form that he will send back to Alice, including his responses for all the fields Alice sent him except that he MUST NOT include a 'dhhashes' field.</p>
<p>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>
<p>He MUST set the 'init_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>
<p>Bob MUST encapsulate the Base64 encoded values of &CsubA; and Alice's &NsubA; in two new 'counter' and 'nonce' fields and append them to the form.</p>
<p>If this is a 4-message negotiation Bob SHOULD respond to Alice by sending her the form (&formB;) immediately - there is nothing more for him to do until he receives Alice's next message (i.e. he can skip the following sections). If this is a 3-message negotiation Bob MUST NOT send the form until he has completed the steps in the following sections.</p>
<example caption='Bob Responds to Alice (4-Message Negotiation only)'><![CDATA[
@ -447,33 +456,34 @@
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='submit' xmlns='jabber:x:data'>
<field var="FORM_TYPE">
<field var='FORM_TYPE'>
<value>urn:xmpp:ssn</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>http://www.w3.org/2000/09/xmldsig#rsa-sha256</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">
<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>http://www.w3.org/2000/09/xmldsig#rsa-sha256</value></field>
<field var='compress'><value>none</value></field>
<field var='stanzas'><value>message</value></field>
<field var='init_pubkey'><value>hash</value></field>
<field var='resp_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="sas_algs"><value>sas28x5</value></field>
<field var="dhkeys">
<field var='sas_algs'><value>sas28x5</value></field>
<field var='dhkeys'>
<value> ** Base64 encoded value of d ** </value>
</field>
<field var="nonce">
<field var='nonce'>
<value> ** Alice's Base64 encoded ESession ID ** </value>
</field>
<field var="counter">
<field var='counter'>
<value> ** Base64 encoded block counter ** </value>
</field>
</x>
@ -497,22 +507,22 @@
<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, unless it will be used later to generate the final shared secret (see <link url='#init-finalbob'>Generating Bob's Final Session Keys</link> or <link url='#init-finalalice'>Generating Alice's Final Session Keys</link>).</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>
<p>Once the sets of keys have been calculated the value of K MUST be securely destroyed, unless it will be used later to generate the final shared secret (see <link url='#init-finalbob'>Generating Bob's Final Session Keys</link>.</p>
</section3>
<section3 topic="Hiding Bob's 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 'none' then Bob MUST set &pubKeyB; to a zero length string of characters. Otherwise Bob SHOULD select &pubKeyB;, which MUST be a <link url='#sign-normal'>Normalized</link> &lt;KeyValue/&gt; element (as specified in <cite>XML Signature</cite>). This is the public key Alice will use to authenticate his signature with the signature algorithm he selected ("SIGN").</p></li>
<li><p>Bob MUST select one method of identification from the values in the 'resp_pubkey' field he received from Alice. If he selects the 'none' method of identification then he MUST set &pubKeyB; to a zero length string of characters. Otherwise Bob SHOULD select &pubKeyB;, which MUST be a <link url='#sign-normal'>Normalized</link> &lt;KeyValue/&gt; element (as specified in <cite>XML Signature</cite>). This is the public key Alice will use to authenticate his signature with the signature algorithm he selected ("SIGN").</p></li>
<li><p>Set &formB; to be the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the reponse data form he generated above (see <link url='#init-online-form'>Response Form</link>). Note: this MUST NOT include '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 (as defined in Section 2 of &rfc2104;) of the resulting byte string using the selected hash algorithm ("HASH") and the key &KSsubB;.</p>
<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 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 <em>not</em> 'none' then Bob MUST calculate &signB;, the signature (using his private signature key that corresponds to &pubKeyB;) of the HMAC result wrapped in a &lt;SignatureValue/&gt; element. Note: &signB; MUST be calculated as specified in <cite>XML Signature</cite> except that it is signature of the HMAC result, <em>not</em> of a &lt;SignedInfo/&gt; element.</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 wrapped in a &lt;fingerprint/&gt; element</p>
<code>if (pubkey == 'hash') &pubKeyB; = '&lt;fingerprint&gt;' + HASH(&pubKeyB;) + '&lt;/fingerprint&gt;'</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>
<li><p>If the value of the 'resp_pubkey' field that Alice sent Bob was <em>not</em> 'none' then Bob MUST calculate &signB;, the signature (using his private signature key that corresponds to &pubKeyB;) of the HMAC result wrapped in a &lt;SignatureValue/&gt; element. Note: &signB; MUST be calculated as specified in <cite>XML Signature</cite> except that it is signature of the HMAC result, <em>not</em> of a &lt;SignedInfo/&gt; element.</p>
<code>if (resp_pubkey != 'none') &signB; = SIGN(&signKeyB;, &macB;)</code></li>
<li><p>If the value of the 'resp_pubkey' field that Alice sent Bob was 'hash' then Bob SHOULD set &pubKeyB; to the key's fingerprint wrapped in a &lt;fingerprint/&gt; element</p>
<code>if (resp_pubkey == 'hash') &pubKeyB; = '&lt;fingerprint&gt;' + HASH(&pubKeyB;) + '&lt;/fingerprint&gt;'</code></li>
<li><p>Encrypt the byte string resulting from the concatenation of &pubKeyB; and &signB; (or, if the value of the 'resp_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>
@ -528,28 +538,28 @@
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x type='submit' xmlns='jabber:x:data'>
<field var="FORM_TYPE">
<field var='FORM_TYPE'>
<value>urn:xmpp:ssn</value>
</field>
...
...
...
<field var="my_nonce">
<field var='my_nonce'>
<value> ** Bob's Base64 encoded ESession ID ** </value>
</field>
<field var="dhkeys">
<field var='dhkeys'>
<value> ** Base64 encoded value of d ** </value>
</field>
<field var="nonce">
<field var='nonce'>
<value> ** Alice's Base64 encoded ESession ID ** </value>
</field>
<field var="counter">
<field var='counter'>
<value> ** Base64 encoded block counter ** </value>
</field>
<field var="identity">
<field var='identity'>
<value> ** Encrypted identity ** </value>
</field>
<field var="mac">
<field var='mac'>
<value> ** Integrity of identity ** </value>
</field>
</x>
@ -570,7 +580,7 @@
<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 - see <link url='#init-online-request'>ESession Request</link>)</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 exactly the same way as Bob did (see <link url='#init-keys'>Generating Session Keys</link>). Note: In the case of 4-message negotiation it is only necessary to generate the keys for the messages Alice sends to Bob (&KCsubA;, &KMsubA;, &KSsubA;).</p></li>
<li><p>Generate the session keys (&KCsubA;, &KMsubA;, &KSsubA;, &KCsubB;, &KMsubB; and &KSsubB;) in exactly the same way as Bob did (see <link url='#init-keys'>Generating Session Keys</link>). Note: In the case of 4-message negotiation it is only necessary to generate provisory keys for the messages Alice sends to Bob (&KCsubA;, &KMsubA;, &KSsubA;).</p></li>
</ol>
<p>If this is a 4-message negotiation then Alice MUST skip the next section and proceed by executing the steps in the <link url='#init-acceptalice-hide'>Hiding Alice's Identity</link> section.</p>
</section3>
@ -580,27 +590,27 @@
<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 &macB; (if the value of the 'pubkey' field she sent to Bob in her <link url='#init-online-request'>ESession Request</link> was 'none') or &pubKeyB; and &signB; (otherwise) 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>
<li><p>Obtain &macB; (if the value of the 'resp_pubkey' field she sent to Bob in her <link url='#init-online-request'>ESession Request</link> was 'none') or &pubKeyB; and &signB; (otherwise) 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>&macB; = DECIPHER(&KCsubB;, &CsubB;, &IDB;)</code>
<p>or</p>
<code>{&pubKeyB;, &signB;} = DECIPHER(&KCsubB;, &CsubB;, &IDB;)</code></li>
<li><p>If the value of the 'pubkey' field that Alice sent Bob was 'none' then Alice MUST set &pubKeyB; to be a zero length string of characters. Otherwise, if the value was 'hash', then Alice SHOULD change the value of &pubKeyB; to be her copy of the public key (a <link url='#sign-normal'>Normalized</link> &lt;KeyValue/&gt; element) whose HASH matches the value wrapped in the &pubKeyB; &lt;fingerprint/&gt; element that she received from Bob.</p>
<p>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>If the value of the 'resp_pubkey' field that Alice sent Bob was 'none' then Alice MUST set &pubKeyB; to be a zero length string of characters. Otherwise, if the value was 'hash', then Alice SHOULD change the value of &pubKeyB; to be her copy of the public key (a <link url='#sign-normal'>Normalized</link> &lt;KeyValue/&gt; element) whose HASH matches the value wrapped in the &pubKeyB; &lt;fingerprint/&gt; element that she received from Bob.</p>
<p>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 'resp_pubkey' field set to 'key' or 'none'.</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>If the value of the 'pubkey' field that Alice sent Bob was 'none' then return a &feature; error to Bob if the two values of &macB; she calculated above do not match.</p>
<p>If the value of the 'pubkey' field was not 'none', return a &feature; error unless she can confirm (or has previously confirmed) that &pubKeyB; really is Bob's public key (see <link url='#sec-keys'>Verifying Keys</link>) and she can use &pubKeyB; with the selected signature verification algorithm ("VERIFY") to confirm that &signB; is the signature of the HMAC result (see <cite>XML Signature</cite>).</p>
<li><p>If the value of the 'resp_pubkey' field that Alice sent Bob was 'none' then return a &feature; error to Bob if the two values of &macB; she calculated in the steps above do not match.</p>
<p>If the value of the 'resp_pubkey' field was not 'none', return a &feature; error unless she can confirm (or has previously confirmed) that &pubKeyB; really is Bob's public key (see <link url='#sec-keys'>Verifying Keys</link>) and she can use &pubKeyB; with the selected signature verification algorithm ("VERIFY") to confirm that &signB; is the signature of the HMAC result (see <cite>XML Signature</cite>).</p>
<code>VERIFY(&signB;, &pubKeyB;, &macB;)</code></li>
</ol>
</section3>
<section3 topic="Hiding Alice's Identity" anchor='init-acceptalice-hide'>
<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 Bob's Identity</link> for a more detailed description). Alice's calculations are summarised below. Note: When calculating &macA; pay attention to the order of &NsubB; and &NsubA; and to the inclusion of &formA2;.</p>
<p>Note: &formA; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the <link url='#init-online-request'>ESession Request</link> data form that Alice sent to Bob at the start of the negotiation, while &formA2; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of Alice's session negotiation completion form excluding the 'identity' and 'mac' fields (see <link url='#init-acceptalice-send'>Sending Alice's Identity</link> below).</p>
<p>Note: &formA; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the <link url='#init-online-request'>ESession Request</link> data form that Alice sent to Bob at the start of the negotiation, while &formA2; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of Alice's session negotiation completion form <em>excluding</em> the 'identity' and 'mac' fields (see <link url='#init-acceptalice-send'>Sending Alice's Identity</link> below).</p>
<code>&macA; = <em>HMAC</em>(HASH, &KSsubA;, {&NsubB;, &NsubA;, e, &pubKeyA;, &formA;, &formA2;})</code>
<code>&signA; = SIGN(&signKeyA;, &macA;)</code>
<code>if (pubkey == 'hash') &pubKeyA; = HASH(&pubKeyA;)</code>
<code>if (init_pubkey != 'none') &signA; = SIGN(&signKeyA;, &macA;)</code>
<code>if (init_pubkey == 'hash') &pubKeyA; = HASH(&pubKeyA;)</code>
<code>&IDA; = CIPHER(&KCsubA;, &CsubA;, {&pubKeyA;, &signA;}) <em>OR</em>&#160; &IDA; = CIPHER(&KCsubA;, &CsubA;, &macA;)</code>
<code>&MsubA; = <em>HMAC</em>(HASH, &KMsubA;, &CsubA;, &IDA;)</code>
</section3>
@ -613,11 +623,11 @@
<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:ssn</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>
<field var='FORM_TYPE'><value>urn:xmpp:ssn</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'>
@ -633,20 +643,20 @@
<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:ssn</value></field>
<field var="accept"><value>1</value></field>
<field var="nonce"><value> ** Bob's Base64 encoded ESession ID ** </value></field>
<field type="hidden" var="dhkeys">
<field var='FORM_TYPE'><value>urn:xmpp:ssn</value></field>
<field var='accept'><value>1</value></field>
<field var='nonce'><value> ** Bob's Base64 encoded ESession ID ** </value></field>
<field type='hidden' var='dhkeys'>
<value> ** Base64 encoded value of e5 ** </value>
</field>
<field type="hidden" var="rshashes">
<field type='hidden' var='rshashes'>
<value> ** Base64 encoded hash of retained secret ** </value>
<value> ** Base64 encoded hash of retained secret ** </value>
<value> ** Base64 encoded random value ** </value>
<value> ** Base64 encoded random value ** </value>
</field>
<field var="identity"><value> ** Encrypted identity ** </value></field>
<field var="mac"><value> ** Integrity of identity ** </value></field>
<field var='identity'><value> ** Encrypted identity ** </value></field>
<field var='mac'><value> ** Integrity of identity ** </value></field>
</x>
</feature>
</message>
@ -661,10 +671,10 @@
<li><p>Return a &feature; error unless SHA256(e) equals 'He', the value he received from Alice in her original session request.</p></li>
<li><p>Return a &feature; error unless: 1 &lt; e &lt; p - 1</p></li>
<li><p>Use the value of e he received from Alice, his secret value of y and their agreed value of p to calculate the value of the Diffie-Hellman shared secret: K = HASH(&esupy; mod p)</p></li>
<li><p>Generate Alice's session keys (&KCsubA;, &KMsubA;, &KSsubA;) in exactly the same way as specified for 3-message negotiations in the <link url='#init-keys'>Generating Session Keys</link> section.</p></li>
<li><p>Generate Alice's provisory session keys (&KCsubA;, &KMsubA;, &KSsubA;) in exactly the same way as specified for 3-message negotiations in the <link url='#init-keys'>Generating Session Keys</link> section.</p></li>
</ol>
<p>After receiving Alice's identity Bob MUST verify it by performing steps equivalent to those performed by Alice above (see <link url='#init-online-bobid'>Verifying Bob's Identity</link> for a more detailed description). Some of Bob's calculations are summarised below. Note: When calculating &macA; pay attention to the order of &NsubB; and &NsubA; and to the inclusion of &formA2;.</p>
<p>Note: &formA; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the <link url='#init-online-request'>ESession Request</link> data form that Alice sent to Bob at the start of the negotiation, while &formA2; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of Alice's session negotiation completion form excluding the 'identity' and 'mac' fields (see <link url='#init-acceptalice-send'>Sending Alice's Identity</link>).</p>
<p>Note: &formA; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of the <link url='#init-online-request'>ESession Request</link> data form that Alice sent to Bob at the start of the negotiation, while &formA2; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of Alice's session negotiation completion form <em>excluding</em> the 'identity' and 'mac' fields (see <link url='#init-acceptalice-send'>Sending Alice's Identity</link>).</p>
<p>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>&macA; = DECIPHER(&KCsubA;, &CsubA;, &IDA;) <em>OR</em> {&pubKeyA;, &signA;} = DECIPHER(&KCsubA;, &CsubA;, &IDA;)</code>
@ -681,16 +691,16 @@
<section3 topic="Generating Bob's Final Session Keys" anchor='init-finalbob'>
<p>Bob MUST identify the shared retained secret (SRS) by selecting from his client's list of the secrets it retained from previous sessions with Alice's clients (i.e., secrets from sessions where the bareJID was the same as the one Alice is currently using). Note: The list contains the most recent shared secret for each of Alice's clients that she has previously used to negotiate ESessions with the client Bob is currently using.</p>
<p>Bob does this by calculating the HMAC (using HASH and the key &NsubA;) of each secret in the list in turn and comparing it with each of the values in the 'rshashes' field he received from Alice (see <link url='#init-acceptalice-send'>Sending Alice's Identity</link>). Once he finds a match, and has confirmed that the secret has not expired (because it is older than an implementation-defined period of time), then he has found the SRS.</p>
<p>If Bob cannot find a match, then he SHOULD search through all the retained secrets that have not expired for all the other JIDs his client has communicated with to try to find a match with one of the values in the 'rshashes' field he received from Alice (since she may simply be using a different JID, perhaps in order to protect her identity from third parties). Resource-constrained implementations MAY make the performance of this extended search an optional feature.</p>
<p>If Bob cannot find a match, then he SHOULD search through all the retained secrets that have not expired for all the other JIDs his client has communicated with to try to find a match with one of the values in the 'rshashes' field he received from Alice (since she may simply be using a different JID, perhaps in order to protect her identity from third parties). Once he finds a match then he has found the SRS. Note: Resource-constrained implementations MAY make the performance of this second extended search an optional feature.</p>
<p>Bob MUST calculate the final session key by appending to K (the Diffie-Hellman shared secret) the SRS (only if one was found) and then the Other Shared Secret (only if one exists) and then setting K to be the HASH result of the concatenated string of bytes:</p>
<code>K = HASH(K | SRS | OSS)</code>
<p>Bob MUST now use the new value of K to generate the new session keys (&KCsubA;, &KMsubA;, &KCsubB;, &KMsubB; and &KSsubB;) in exactly the same way as he does for 3-message negotiations (see <link url='#init-keys'>Generating Session Keys</link>). These keys will be used to exchange encrypted stanzas. Note: Bob will still need the value of K in the next section.</p>
</section3>
<section3 topic="Sending Bob's Identity" anchor='init-acceptbob-send'>
<p>Bob MUST now prove his identity to Alice while protecting it from third parties. He does this in the same way as he does for 3-message negotiations (see <link url='#init-hide'>Hiding Bob's Identity</link> for a more detailed description) except that, when calculating &macA;, he MUST include &formB2;:</p>
<p>Bob MUST now prove his identity to Alice while protecting it from third parties. He does this in the same way as he does for 3-message negotiations (see <link url='#init-hide'>Hiding Bob's Identity</link> for a more detailed description) except that, when calculating &macB;, he MUST include &formB2;:</p>
<code>&macB; = <em>HMAC</em>(HASH, &KSsubB;, {&NsubA;, &NsubB;, d, &pubKeyB;, &formB;, &formB2;})</code>
<p>Note: &formB2; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of Bob's session negotiation completion form excluding the 'identity' and 'mac' fields (see below).</p>
<p>Note: &formB2; is the full <link url='#sign-normal'>Normalized</link>&#160;<em>content</em> of Bob's session negotiation completion form <em>excluding</em> the 'identity' and 'mac' fields (see below).</p>
<p>Bob MUST send Alice the Base64 encoded value of the HMAC (using HASH and the key SRS) of the string "Shared Retained Secret" (wrapped in an 'srshash' field). If no SRS was found then he MUST use a random number instead. <note>Bob always sends a value in the 'srshash' field to prevent an attacker learning that the session is not protected by a retained secret.</note></p>
<code><em>HMAC</em>(HASH, SRS, "Shared Retained Secret")</code>
<p>Bob MUST also include in the data form the Base64 encoded values of &NsubA;, and &IDB; and &MsubB; (that he just calculated). Note: He MAY also send encrypted content (see <cite>Stanza Encryption</cite>) in the same stanza.</p>
@ -699,17 +709,18 @@
<thread>ffd7076498744578d10edabfe7f4a866</thread>
<init xmlns='urn:xmpp:esession#init'>
<x type='result' xmlns='jabber:x:data'>
<field var="FORM_TYPE"><value>urn:xmpp:ssn</value></field>
<field var="nonce"><value> ** Alice's Base64 encoded ESession ID ** </value></field>
<field var="srshash"><value> ** HMAC with shared retained secret ** </value></field>
<field var="identity"><value> ** Encrypted identity ** </value></field>
<field var="mac"><value> ** Integrity of identity ** </value></field>
<field var='FORM_TYPE'><value>urn:xmpp:ssn</value></field>
<field var='nonce'><value> ** Alice's Base64 encoded ESession ID ** </value></field>
<field var='srshash'><value> ** HMAC with shared retained secret ** </value></field>
<field var='identity'><value> ** Encrypted identity ** </value></field>
<field var='mac'><value> ** Integrity of identity ** </value></field>
</x>
</init>
</message>
]]></example>
<p>Finally, Bob MUST destroy all his copies of SRS (the retained secret he was keeping for Alice's client), calculate a new retained secret for this session (see below) and <em>securely</em> store the new value along with the other retained secrets his client shares with Alice's clients:</p>
<p>Finally, Bob MUST destroy all his copies of the old retained secret (SRS) he was keeping for Alice's client, and calculate a new retained secret for this session:</p>
<code><em>HMAC</em>(HASH, K, "New Retained Secret")</code>
<p>Bob MUST <em>securely</em> store the new value along with the retained secrets his client shares with Alice's other clients.</p>
<p>Bob's value of K MUST now be securely destroyed.</p>
</section3>
</section2>
@ -734,7 +745,7 @@
<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 stanza session negotiation form with a "terminate" field (as specified in the Termination section of <cite>Stanza 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>
<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 (see <cite>Stanza Encryption</cite>) to Bob including within the encrypted XML of the &lt;data/&gt; element a stanza session negotiation form with a "terminate" field (as specified in the Termination section of <cite>Stanza 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>
@ -790,7 +801,7 @@
</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 (wrapped in a &lt;KeyValue/&gt; element) 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>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. In the case of retained secrets entities SHOULD remember whether or not the whole chain of retained secrets (and the associated sessions) has ever been validated by the user verifying a SAS.</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'>
@ -814,7 +825,7 @@
</section2>
</section1>
<section1 topic='Mandatory to Implement Technologies' anchor='sec-mandatory'>
<p>An implementation of ESession MUST support the Diffie-Hellman Key Agreement and HMAC algorithms. Note: Some of 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 some of the other names.</p>
<p>An implementation of ESession MUST support the Diffie-Hellman Key Agreement and HMAC (see Section 2 of &rfc2104;) algorithms. Note: Some of 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 some of the other names.</p>
<section2 topic='Block Cipher Algorithms' anchor='sec-mandatory-encryption'>
<p>An implementation of ESession MUST support the following block cipher algorithm:</p>
<ul>
@ -889,7 +900,7 @@
<ol>
<li><p>Concatenate &MsubA;, &formB; and the UTF-8 byte string "Short Authentication String" into a string of bytes</p></li>
<li><p>Calculate the least significant 24-bits of the HASH of the string</p></li>
<li><p>Convert the 24-bit integer into a base-28 <note>Base-28 was used instead of Base-36 because some characters are often confused when communicated verbally (n, s, b, t, z, j), and because zero is often read as the letter 'o', and the letter 'l' is often read as the number '1'.</note> 5-character string using the following digits (values 0-27): acdefghikmopqruvwxy123456789</p></li>
<li><p>Convert the 24-bit integer into a base-28 <note>Base-28 was used instead of Base-36 because some characters are often confused when communicated verbally (n, s, b, t, z, j), and because zero is often read as the letter 'o', and the letter 'l' is often read as the number '1'.</note> 5-character string using the following "digits": acdefghikmopqruvwxy123456789 (the digits have values 0-27)</p></li>
</ol>
</section1>
@ -910,7 +921,7 @@
<code caption='Registry Submission'><![CDATA[
<form_type>
<name>urn:xmpp:esession</name>
<jep>XEP-0116</jep>
<doc>XEP-0116</doc>
<desc>ESession negotiation forms</desc>
<field
var='compress'
@ -957,9 +968,23 @@
type='hidden'
label='ESession ID of Receiver'/>
<field
var='pubkey'
var='init_pubkey'
type='list-single'
label='Respond with public key'>
label='Initiator public key required'>
<option label='No Key'>
<value>none</value>
</option>
<option label='Full Key'>
<value>key</value>
</option>
<option label='Key Fingerprint'>
<value>hash</value>
</option>
</field>
<field
var='resp_pubkey'
type='list-single'
label='Responder public key required'>
<option label='No Key'>
<value>none</value>
</option>
@ -1020,7 +1045,7 @@
<form_type>
<name>urn:xmpp:ssn</name>
<jep>XEP-0155</jep>
<doc>XEP-0155</doc>
...
</form_type>
]]></code>