RFC 3923
End-to-End Signing and Object Encryption for the Extensible Messaging and Presence Protocol (XMPP)
RFC 3923: End-to-End Signing and Object Encryption for the Extensible Messaging and Presence Protocol (XMPP) π
Okay bestie, first the receipts π§Ύ. This is RFC 3923, written by P. Saint-Andre of the Jabber Software Foundation in October 2004. It's on the Standards Track π€οΈ and it's part of the Network Working Group series. The title block doesn't list anything it obsoletes or updates, so no other RFC gets replaced or patched here. π
Status of this Memo β¨
So this doc is a standards track protocol spec for the whole Internet community, and it's literally asking for discussion and suggestions for improvements π£οΈ (I love that for us). For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) π. Distribution of this memo is unlimited π.
Copyright Notice π
Copyright (C) The Internet Society (2004).
Abstract πΈ
The tea is simple: this memo defines methods of end-to-end signing and object encryption for XMPP π.
Table of Contents π
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Requirements . . . . . . . . . . . . . . . . . . . . . . . . 2
3. Securing Messages . . . . . . . . . . . . . . . . . . . . . 4
4. Securing Presence . . . . . . . . . . . . . . . . . . . . . 9
5. Securing Arbitrary XMPP Data . . . . . . . . . . . . . . . . 13
6. Rules for S/MIME Generation and Handling . . . . . . . . . . 15
7. Recipient Error Handling . . . . . . . . . . . . . . . . . . 18
8. Secure Communications Through a Gateway . . . . . . . . . . 20
9. urn:ietf:params:xml:xmpp-e2e Namespace . . . . . . . . . . . 21
10. application/xmpp+xml Media Type . . . . . . . . . . . . . . 21
11. Security Considerations . . . . . . . . . . . . . . . . . . 22
12. IANA Considerations . . . . . . . . . . . . . . . . . . . . 22
13. References . . . . . . . . . . . . . . . . . . . . . . . . . 23
A. Schema for urn:ietf:params:xml:ns:xmpp-e2e . . . . . . . . . 26
Author's Address. . . . . . . . . . . . . . . . . . . . . . . . . 26
Full Copyright Statement. . . . . . . . . . . . . . . . . . . . . 27
1. Introduction π¦
Okay so this memo defines methods of end-to-end signing and object encryption for the Extensible Messaging and Presence Protocol (XMPP). If you want the XMPP basics, see [XMPP-CORE] and [XMPP-IM] π. The vibe is that a sender can sign and/or encrypt an instant message sent to a specific recipient π, sign and/or encrypt presence information that's directed to a specific user π, and sign and/or encrypt any arbitrary XMPP stanza directed to a specific user π. This memo basically helps the XMPP specs meet the requirements specified in [IMP-REQS] β¨.
1.1. Terminology π
This document inherits terminology defined in [CMS], [IMP-MODEL], [SMIME], and [XMPP-CORE].
The capitalized key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, RFC 2119 [TERMS]. Those are the BCP 14 key words, and they're the ones that carry the real weight π―.
2. Requirements π
Here's what we're locking in for this memo:
- The method defined MUST address signing and encryption requirements for minimal instant messaging and presence, as those are defined in [IMP-REQS]. In particular, the method MUST address the following requirements, which are copied here verbatim from [IMP-REQS]:
- "The protocol MUST provide means to ensure confidence that a received message (NOTIFICATION or INSTANT MESSAGE) has not been corrupted or tampered with." (Section 2.5.1)
- "The protocol MUST provide means to ensure confidence that a received message (NOTIFICATION or INSTANT MESSAGE) has not been recorded and played back by an adversary." (Section 2.5.2)
- "The protocol MUST provide means to ensure that a sent message (NOTIFICATION or INSTANT MESSAGE) is only readable by ENTITIES that the sender allows." (Section 2.5.3)
- "The protocol MUST allow any client to use the means to ensure non-corruption, non-playback, and privacy, but the protocol MUST NOT require that all clients use these means at all times." (Section 2.5.4)
- "When A establishes a SUBSCRIPTION to B's PRESENCE INFORMATION, the protocol MUST provide A means of verifying the accurate receipt of the content B chooses to disclose to A." (Section 5.1.4)
- "The protocol MUST provide A means of verifying that the presence information is accurate, as sent by B." (Section 5.3.1)
- "The protocol MUST provide A means of ensuring that no other PRINCIPAL C can see the content of M." (Section 5.4.6)
- "The protocol MUST provide A means of ensuring that no other PRINCIPAL C can tamper with M, and B means to verify that no tampering has occurred." (Section 5.4.7)
- The method defined MUST enable interoperability with non-XMPP messaging systems that support the Common Presence and Instant Messaging (CPIM) specifications published by the Instant Messaging and Presence (IMPP) Working Group. Two corollaries of this requirement are:
- Prior to signing and/or encrypting, the format of an instant message MUST conform to the CPIM Message Format defined in [MSGFMT].
- Prior to signing and/or encrypting, the format of presence information MUST conform to the CPP Presence Information Data Format defined in [PIDF].
- The method MUST follow the required procedures (including the specific algorithms) defined in [CPIM] and [CPP]. In particular, these documents specify:
- Signing MUST use [SMIME] signatures with [CMS] SignedData.
- Encryption MUST use [SMIME] encryption with [CMS] EnvelopeData.
- In order to enable interoperable implementations, sending and receiving applications MUST implement the algorithms specified under Mandatory-to-Implement Cryptographic Algorithms (Section 6.10).
We're also stipulating that the following stuff is out of scope for this memo π«:
- Discovery of support for this protocol. An entity could discover whether another entity supports this protocol by (1) attempting to send signed or encrypted stanzas and receiving an error stanza ("technical" discovery) or a textual message in reply ("social" discovery) if the protocol is not supported, or (2) using a dedicated service discovery protocol, such as [DISCO] or [CAPS]. However, the definition of a service discovery protocol is out of scope for this memo.
- Signing or encryption of XMPP groupchat messages, which are mentioned in [XMPP-IM] but not defined therein since they are not required by [IMP-REQS]; such messages are best specified in [MUC].
- Signing or encryption of broadcasted presence as described in [XMPP-IM] (the methods defined herein apply to directed presence only).
- Signing or encryption of communications that occur within the context of applications other than instant messaging and presence as those are described in [IMP-MODEL] and [IMP-REQS].
3. Securing Messages π
3.1. Process for Securing Messages π‘οΈ
Okay, step by step, because this part is important π. In order to sign and/or encrypt a message, a sending agent MUST use the following procedure:
- Generate a
Message/CPIMobject as defined in [MSGFMT]. - Sign and/or encrypt both the headers and content of the
Message/CPIMobject as specified in Requirement 3 of Section 2 above. - Provide the resulting signed and/or encrypted object within an XML CDATA section (see Section 2.7 of [XML]) contained in an
<e2e/>child of a<message/>stanza, where the<e2e/>element is qualified by the'urn:ietf:params:xml:ns:xmpp-e2e'namespace as specified more fully in Section 9 below.
3.2. Example of a Signed Message π¦’
Here's the whole thing in action. First, the sending agent generates a Message/CPIM object following the rules and formats in [MSGFMT] π.
Example 1: Sender generates "Message/CPIM" object:
| Content-type: Message/CPIM
|
| From: Juliet Capulet <im:juliet@example.com>
| To: Romeo Montague <im:romeo@example.net>
| DateTime: 2003-12-09T11:45:36.66Z
| Subject: Imploring
|
| Content-type: text/plain; charset=utf-8
| Content-ID: <1234567890@example.com>
|
| Wherefore art thou, Romeo?
Once the sending agent has generated the "Message/CPIM" object, it may sign it ποΈ. The result is a multipart [SMIME] object (see [MULTI]) with a Content-Type of "multipart/signed", and it has two parts: one whose Content-Type is "Message/CPIM" and another whose Content-Type is "application/pkcs7-signature" π.
Example 2: Sender generates multipart/signed object:
| Content-Type: multipart/signed; boundary=next;
| micalg=sha1;
| protocol=application/pkcs7-signature
|
| --next
| Content-type: Message/CPIM
|
| From: Juliet Capulet <im:juliet@example.com>
| To: Romeo Montague <im:romeo@example.net>
| DateTime: 2003-12-09T23:45:36.66Z
| Subject: Imploring
|
| Content-type: text/plain; charset=utf-8
| Content-ID: <1234567890@example.com>
|
| Wherefore art thou, Romeo?
| --next
| Content-Type: application/pkcs7-signature
| Content-Disposition: attachment;handling=required;\
| filename=smime.p7s
|
| [signed body part]
|
| --next--
The sending agent now wraps the "multipart/signed" object in an XML CDATA section π. That section sits inside an <e2e/> element, which is a child of the XMPP message stanza and is qualified by the 'urn:ietf:params:xml:ns:xmpp-e2e' namespace π§.
Example 3: Sender generates XMPP message stanza:
| <message to='romeo@example.net/orchard' type='chat'>
| <e2e xmlns='urn:ietf:params:xml:ns:xmpp-e2e'>
| <![CDATA[
| Content-Type: multipart/signed; boundary=next;
| micalg=sha1;
| protocol=application/pkcs7-signature
|
| --next
| Content-type: Message/CPIM
|
| From: Juliet Capulet <im:juliet@example.com>
| To: Romeo Montague <im:romeo@example.net>
| DateTime: 2003-12-09T23:45:36.66Z
| Subject: Imploring
|
| Content-type: text/plain; charset=utf-8
| Content-ID: <1234567890@example.com>
|
| Wherefore art thou, Romeo?
| --next
| Content-Type: application/pkcs7-signature
| Content-Disposition: attachment;handling=required;\
| filename=smime.p7s
|
| [signed body part]
|
| --next--
| ]]>
| </e2e>
| </message>
3.3. Example of an Encrypted Message
okay so this one walks through the steps for encrypting a message πβ¨ the sending agent starts by making a "Message/CPIM" object, following the rules and formats in [MSGFMT] π
Example 4: Sender generates "Message/CPIM" object:
| Content-type: Message/CPIM
|
| From: Juliet Capulet <im:juliet@example.com>
| To: Romeo Montague <im:romeo@example.net>
| DateTime: 2003-12-09T11:45:36.66Z
| Subject: Imploring
|
| Content-type: text/plain; charset=utf-8
| Content-ID: <1234567890@example.com>
|
| Wherefore art thou, Romeo?
once the sending agent has the "Message/CPIM" object, it may encrypt it π₯Ή
Example 5: Sender generates encrypted object:
| U2FsdGVkX19okeKTlLxa/1n1FE/upwn1D20GhPWqhDWlexKMUKYJInTWzERP+vcQ
| /OxFs40uc9Fx81a5/62p/yPb/UWnuG6SR6o3Ed2zwcusDImyyz125HFERdDUMBC9
| Pt6Z4cTGKBmJzZBGyuc3Y+TMBTxqFFUAxeWaoxnZrrl+LP72vwbriYc3KCMxDbQL
| Igc1Vzs5/5JecegMieNY24SlNyX9HMFRNFpbI64vLxYEk55A+3IYbZsluCFT31+a
| +GeAvJkvH64LRV4mPbUhENTQ2wbAwnOTvbLIaQEQrii78xNEh+MK8Bx7TBTvi4yH
| Ddzf9Sim6mtWsXaCAvWSyp0X91d7xRJ4JIgKfPzkxNsWJFCLthQS1p734eDxXVd3
| i08lEHzyll6htuEr59ZDAw==
next the sending agent wraps that encrypted blob in an XML CDATA section π the CDATA section sits inside an <e2e/> element, which is a child of the XMPP message stanza, and the element is qualified by the urn:ietf:params:xml:ns:xmpp-e2e namespace. it's giving neat little gift box π
Example 6: Sender generates XMPP message stanza:
| <message to='romeo@example.net/orchard' type='chat'>
| <e2e xmlns='urn:ietf:params:xml:ns:xmpp-e2e'>
| <![CDATA[
| U2FsdGVkX19okeKTlLxa/1n1FE/upwn1D20GhPWqhDWlexKMUKYJInTWzERP+vcQ
| /OxFs40uc9Fx81a5/62p/yPb/UWnuG6SR6o3Ed2zwcusDImyyz125HFERdDUMBC9
| Pt6Z4cTGKBmJzZBGyuc3Y+TMBTxqFFUAxeWaoxnZrrl+LP72vwbriYc3KCMxDbQL
| Igc1Vzs5/5JecegMieNY24SlNyX9HMFRNFpbI64vLxYEk55A+3IYbZsluCFT31+a
| +GeAvJkvH64LRV4mPbUhENTQ2wbAwnOTvbLIaQEQrii78xNEh+MK8Bx7TBTvi4yH
| Ddzf9Sim6mtWsXaCAvWSyp0X91d7xRJ4JIgKfPzkxNsWJFCLthQS1p734eDxXVd3
| i08lEHzyll6htuEr59ZDAw==
| ]]>
| </e2e>
| </message>
4. Securing Presence πΈ
4.1. Process for Securing Presence Information
okay bestie, listen up π when a sending agent wants to sign and/or encrypt presence info, it MUST follow this procedure:
- Generate an "application/pidf+xml" object as defined in [PIDF].
- Sign and/or encrypt the "application/pidf+xml" object as specified in Requirement 3 of Section 2 above.
- Provide the resulting signed and/or encrypted object within an XML CDATA section (see Section 2.7 of [XML]) contained in an
<e2e/>child of a<presence/>stanza, where the<e2e/>element is qualified by theurn:ietf:params:xml:ns:xmpp-e2enamespace. The<presence/>stanza MUST include a'to'attribute, i.e., it must be an instance of directed presence as defined in [XMPP-IM]. no vibes of a random broadcast here, it has to be aimed at someone π―
4.2. Example of Signed Presence Information
this example shows the steps for signing presence info π¦
First, the sending agent generates an "application/pidf+xml" object in accordance with the rules and formats specified in [PIDF].
Example 7: Sender generates "application/pidf+xml" object:
| <?xml version="1.0" encoding="UTF-8"?>
| <presence xmlns="urn:ietf:params:xml:ns:pidf"
| xmlns:im="urn:ietf:params:xml:ns:pidf:im"
| entity="pres:juliet@example.com">
| <tuple id="hr0zny"
| <status>
| <basic>open</basic>
| <im:im>away</im:im>
| </status>
| <note xml:lang="en">retired to the chamber</note>
| <timestamp>2003-12-09T23:53:11.31</timestamp>
| </tuple>
| </presence>
once that object exists, the sending agent may sign it ποΈ the result is a multipart [SMIME] object (see [MULTI]) with a Content-Type of "multipart/signed", and it has two parts: one labelled "application/pidf+xml" and one labelled "application/pkcs7-signature" π
Example 8: Sender generates multipart/signed object:
| Content-Type: multipart/signed; boundary=next;
| micalg=sha1;
| protocol=application/pkcs7-signature
|
| --next
| Content-type: application/pidf+xml
| Content-ID: <2345678901@example.com>
|
| <xml version="1.0" encoding="UTF-8"?>
| <presence xmlns="urn:ietf:params:xml:ns:pidf"
| xmlns:im="urn:ietf:params:xml:ns:pidf:im"
| entity="pres:juliet@example.com">
| <tuple id="hr0zny">
| <status>
| <basic>open</basic>
| <im:im>away</im:im>
| </status>
| <note xml:lang="en">retired to the chamber</note>
| <timestamp>2003-12-09T23:53:11.31Z</timestamp>
| </tuple>
| </presence>
| --next
| Content-Type: application/pkcs7-signature
| Content-Disposition: attachment;handling=required;\
| filename=smime.p7s
|
| [signed body part]
|
| --next--
the sending agent then wraps the "multipart/signed" object in an XML CDATA section π that section lives in an <e2e/> element, which is a child of the XMPP message stanza, and the element is qualified by the urn:ietf:params:xml:ns:xmpp-e2e namespace π
Example 9: Sender generates XMPP presence stanza:
| <presence to='romeo@example.net/orchard'>
| <e2e xmlns='urn:ietf:params:xml:ns:xmpp-e2e'>
| <![CDATA[
| Content-Type: multipart/signed; boundary=next;
| micalg=sha1;
| protocol=application/pkcs7-signature
|
| --next
| Content-type: application/pidf+xml
| Content-ID: <2345678901@example.com>
|
| <xml version="1.0" encoding="UTF-8"?>
| <presence xmlns="urn:ietf:params:xml:ns:pidf"
| xmlns:im="urn:ietf:params:xml:ns:pidf:im"
| entity="pres:juliet@example.com">
| <tuple id="hr0zny">
| <status>
| <basic>open</basic>
| <im:im>away</im:im>
| </status>
| <note xml:lang="en">retired to the chamber</note>
| <timestamp>2003-12-09T23:53:11.31Z</timestamp>
| </tuple>
| </presence>
| --next
| Content-Type: application/pkcs7-signature
| Content-Disposition: attachment;handling=required;\
| filename=smime.p7s
|
| [signed body part]
|
| --next--
| ]]>
| </e2e>
| </presence>
4.3. Example of Encrypted Presence Information
last one in this part π§ it walks through the steps for encrypting presence info, and it's giving the same vibe as the signed version, just locked up tight π
First, the sending agent generates an "application/pidf+xml" object in accordance with the rules and formats specified in [PIDF].
Example 10: Sender generates "application/pidf+xml" object:
| <?xml version="1.0" encoding="UTF-8"?>
| <presence xmlns="urn:ietf:params:xml:ns:pidf"
| xmlns:im="urn:ietf:params:xml:ns:pidf:im"
| entity="pres:juliet@example.com">
| <tuple id="hr0zny"
| <status>
| <basic>open</basic>
| <im:im>away</im:im>
| </status>
| <note xml:lang="en">retired to the chamber</note>
| <timestamp>2003-12-09T23:53:11.31</timestamp>
| </tuple>
| </presence>
once the sending agent has that object, it may encrypt it π«Ά
Example 11: Sender generates encrypted object:
| U2FsdGVkX18VJPbx5GMdFPTPZrHLC9QGiVP+ziczu6zWZLFQxae6O5PP6iqpr2No
| zOvBVMWvYeRAT0zd18hr6qsqKiGl/GZpAAbTvPtaBxeIykxsd1+CX+U+iw0nEGCr
| bjiQrk0qUKJ79bNxwRnqdidjhyTpKSbOJC0XZ8CTe7AE9KDM3Q+uk+O3jrqX4byL
| GBlKThbzKidxz32ObojPEEwfFiM/yUeqYUP1OcJpUmeQ8lcXhD6tcx+m2MAyYYLP
| boKQxpLknxRnbM8T/voedlnFLbbDu69mOlxDPbr1mHZd3hDsyFudb1fb4rI3Kw0K
| Nq+3udr2IkysviJDgQo+xGIQUG/5sED/mAaPRlj4f/JtTzvT4EaQTawv69ntXfKV
| MCr9KdIMMdjdJzOJkYLoAhNVrcZn5tw8WsJGwuKuhYb/SShy7InzOapPaPAl7/Mm
| PHj7zj3NZ6EEIweDOuAwWlIG/dT506tci27+EW7JnXwMPnFMkF+6a7tr/0Y+iiej
| woJxUIBqCOgX+U7srHpK2NYtNTZ7UQp2V0yEx1JV8+Y=
the sending agent now wraps the encrypted object in an XML CDATA section π which sits in an <e2e/> element, a child of the XMPP message stanza, qualified by the urn:ietf:params:xml:ns:xmpp-e2e namespace β¨
Example 12: Sender generates XMPP presence stanza:
| <presence to='romeo@example.net/orchard'>
| <e2e xmlns='urn:ietf:params:xml:ns:xmpp-e2e'>
| <![CDATA[
| U2FsdGVkX18VJPbx5GMdFPTPZrHLC9QGiVP+ziczu6zWZLFQxae6O5PP6iqpr2No
| zOvBVMWvYeRAT0zd18hr6qsqKiGl/GZpAAbTvPtaBxeIykxsd1+CX+U+iw0nEGCr
| bjiQrk0qUKJ79bNxwRnqdidjhyTpKSbOJC0XZ8CTe7AE9KDM3Q+uk+O3jrqX4byL
| GBlKThbzKidxz32ObojPEEwfFiM/yUeqYUP1OcJpUmeQ8lcXhD6tcx+m2MAyYYLP
| boKQxpLknxRnbM8T/voedlnFLbbDu69mOlxDPbr1mHZd3hDsyFudb1fb4rI3Kw0K
| Nq+3udr2IkysviJDgQo+xGIQUG/5sED/mAaPRlj4f/JtTzvT4EaQTawv69ntXfKV
| MCr9KdIMMdjdJzOJkYLoAhNVrcZn5tw8WsJGwuKuhYb/SShy7InzOapPaPAl7/Mm
| PHj7zj3NZ6EEIweDOuAwWlIG/dT506tci27+EW7JnXwMPnFMkF+6a7tr/0Y+iiej
| woJxUIBqCOgX+U7srHpK2NYtNTZ7UQp2V0yEx1JV8+Y=
| ]]>
| </e2e>
| </presence>
5. Securing Arbitrary XMPP Data π
Okay so everything we've covered so far is about securing "least common denominator" messages and presence data, the kind that can be translated straight into MSGFMT or PIDF formats. πΈ But XMPP also has a third base-level stanza type, <iq/>, on top of <message/> and <presence/>. And you can stuff extended XML data into arbitrary child elements of all three core stanza types. π So it would be super desirable to secure that stuff too, if possible.
Because [MSGFMT] lets you encapsulate any MIME type, this memo puts arbitrary XMPP data into an XML media type called "application/xmpp+xml". Section 10 below covers it in more detail. β¨
Here are some examples of what the "application/xmpp+xml" MIME type looks like. π§ (Quick note: the 'http://jabber.org/protocol/evil' namespace in these examples belongs to an April Fool's protocol, the instant messaging version of RFC 3514. It's only there as an example of extra info in an XML stanza, so please don't take it seriously as a real XMPP extension. π)
Example 13: Message stanza with extended data contained in "application/xmpp+xml" MIME type:
| <?xml version='1.0' encoding='UTF-8'?>
| <xmpp xmlns='jabber:client'>
| <message
| from='iago@example.com/pda'
| to='emilia@example.com/cell'>
| <body>
| I told him what I thought, and told no more
| Than what he found himself was apt and true.
| </body>
| <evil xmlns='http://jabber.org/protocol/evil'/>
| </message>
| </xmpp>
Example 14: Presence stanza with extended data contained in "application/xmpp+xml" MIME type:
| <?xml version='1.0' encoding='UTF-8'?>
| <xmpp xmlns='jabber:client'>
| <presence from='iago@example.com/pda'>
| <show>dnd</show>
| <status>Fomenting dissension</status>
| <evil xmlns='http://jabber.org/protocol/evil'/>
| </presence>
| </xmpp>
Example 15: IQ stanza with extended data contained in "application/xmpp+xml" MIME type:
| <?xml version='1.0' encoding='UTF-8'?>
| <xmpp xmlns='jabber:client'>
| <iq type='result'
| from='iago@example.com/pda'
| to='emilia@example.com/cell'
| id='evil1'>
| <query xmlns='jabber:iq:version'>
| <name>Stabber</name>
| <version>666</version>
| <os>FiendOS</os>
| </query>
| <evil xmlns='http://jabber.org/protocol/evil'/>
| </iq>
| </xmpp>
Just like the "Message/CPIM" and "application/pidf+xml" objects, the "application/xmpp+xml" object can be signed and/or encrypted. Then it gets wrapped in an XML CDATA section (see Section 2.7 of [XML]) that sits inside an <e2e/> child of a <presence/> stanza. The <e2e/> element is qualified by the 'urn:ietf:params:xml:ns:xmpp-e2e' namespace. π
6. Rules for S/MIME Generation and Handling π
6.1. Certificate Enrollment
[SMIME] doesn't say how to get a certificate from a certificate authority. Instead, it insists that every sending agent already has one. π At the time of writing, the PKIX Working Group has produced two separate standards for certificate enrollment: [CMP] and [CMC]. Which one you use for enrollment is outside the scope of this memo.
6.2. Certificate Retrieval
A receiving agent MUST provide some certificate retrieval mechanism so it can access certificates for recipients of digital envelopes. π¬ This memo doesn't cover how S/MIME agents handle certificates, only what they do after a certificate has been validated or rejected. S/MIME certification issues are covered in [CERT].
That said, at a bare minimum for initial S/MIME deployment, a user agent SHOULD automatically generate a message to an intended recipient that asks for that recipient's certificate in a signed return message. π Receiving and sending agents SHOULD also provide a way for a user to "store and protect" certificates for correspondents, in a manner that guarantees they can be retrieved later. π«Ά
6.3. Certificate Names
End-entity certificates used by XMPP entities in the context of this memo SHOULD contain a valid instant messaging and presence address. β¨ That address SHOULD be specified as both an 'im:' URI (for instant messaging, as defined in [CPIM]) and a 'pres:' URI (for presence, as defined in [CPP]). Each of these URIs SHOULD go in its own separate GeneralName entry of type uniformResourceIdentifier inside the subjectAltName, so that's two separate entries, not one. Information in the subject distinguished name SHOULD be ignored. π
Each URI MUST be of the form <im:address> or <pres:address>. The "address" part is an XMPP address (also called a Jabber Identifier or JID) as defined in [XMPP-CORE], with the 'im:' or 'pres:' URI scheme stuck on the front. π¦ The address SHOULD be of the form <node@domain> (that's a "bare JID"), although any valid JID form MAY be used.
The value of the JID in the XMPP 'from' attribute MUST match a JID provided in the signer's certificate. The one exception is the resource identifier portion of the JID in the 'from' attribute, which SHOULD be ignored for matching purposes. π
Receiving agents MUST check that the sending JID matches a JID provided in the signer's certificate. Same exception applies: the resource identifier portion of the JID in the 'from' attribute SHOULD be ignored for matching purposes. A receiving agent SHOULD provide some explicit alternate processing of the stanza if this comparison fails. That could be displaying a message that tells the recipient which addresses are in the certificate, or other certificate details. π¨
The subject alternative name extension is the preferred way S/MIME conveys the instant messaging and presence address that goes with this certificate's entity. π Any XMPP address in the certificate MUST be encoded using the ASN.1 Object Identifier "id-on-xmppAddr", as specified in Section 5.1.1 of [XMPP-CORE]. No vibes-based encoding, bestie. π€
6.4. Transfer Encoding
XMPP applications aren't expected to interface with older 7-bit systems, so the transfer encoding (as defined in Section 3.1.2 of [SMIME]) MUST be "binary". π
6.5. Order of Signing and Encrypting
If a stanza is both signed and encrypted, it SHOULD be signed first and then encrypted. π₯ Sign, then seal it up. Easy.
6.6. Inclusion of Certificates
If the sender and recipient are in an active messaging session over a period of time, the sending agent SHOULD include the sender's certificate along with at least one encrypted message stanza every five minutes. β° Outside of an active messaging session, the sending agent SHOULD include the sender's certificate along with each encrypted message stanza. A sending agent MAY also include the sender's certificate along with each encrypted presence stanza. π§ However, a sending agent SHOULD NOT include a certificate more than once every five minutes. Don't be that friend who keeps sending the same thing. π
6.7. Attachment and Checking of Signatures
Sending agents SHOULD attach a signature to each encrypted XML stanza. π If a signature is attached, a Content-Disposition header field (as defined in [DISP]) SHOULD be included to specify how the receiving application should handle the signature.
If the receiving agent decides the signature attached to an encrypted XML stanza is invalid, it SHOULD NOT present the stanza to the intended recipient (human or application). It SHOULD provide some explicit alternate processing of the stanza, which may be a message telling the recipient that the attached signature is invalid. It MAY also return a stanza error to the sender, as described under Recipient Error Handling (Section 7). π«
6.8. Decryption
If the receiving agent can't decrypt the encrypted XML stanza, it SHOULD NOT present the stanza to the intended recipient (human or application). It SHOULD provide some explicit alternate processing of the stanza, which may be a message saying the recipient got a stanza that can't be decrypted. It MAY return a stanza error to the sender as described under Recipient Error Handling (Section 7). π
6.9. Inclusion and Checking of Timestamps
Timestamps are included in "Message/CPIM" and "application/pidf+xml" objects to help prevent replay attacks. β³ All timestamps MUST conform to [DATETIME] and be presented as UTC with no offset, including fractions of a second where appropriate. Unless the sending agent has made a local adjustment to its perceived time or the underlying clock time, the sending agent MUST ensure that the timestamps it sends to the receiver increase monotonically. If the clock returns the same time for multiple requests, it can do that by incrementing the seconds fraction in the timestamp. π°οΈ The following rules apply to the receiving application:
- It MUST verify that the timestamp received is within five minutes of the current time.
- It SHOULD verify that the timestamp received is greater than any timestamp received in the last 10 minutes which passed the previous check.
- If any of the foregoing checks fails, the timestamp SHOULD be presented to the receiving entity (human or application) marked as "old timestamp", "future timestamp", or "decreasing timestamp". The receiving entity MAY return a stanza error to the sender as described under Recipient Error Handling (Section 7). π«£
6.10. Mandatory-to-Implement Cryptographic Algorithms
All implementations MUST support the following algorithms. Implementations MAY support other algorithms as well. π§
For CMS SignedData:
- The SHA-1 message digest as specified in [CMS-ALG] section 2.1.
- The RSA (PKCS #1 v1.5) with SHA-1 signature algorithm, as specified in [CMS-ALG] section 3.2.
For CMS EnvelopedData:
- The RSA (PKCS #1 v1.5) key transport, as specified in [CMS-ALG] section 4.2.1.
- The AES-128 encryption algorithm in CBC mode, as specified in [CMS-AES]. β¨
7. Recipient Error Handling β¨
okay so bestie, picture this: an XMPP entity gets a stanza with signed and/or encrypted data in it, using the protocol in this doc π¨. There are five ways the receiving side can react, and they all matter π
- Case #1: The receiving application does not understand the protocol.
- Case #2: The receiving application understands the protocol and is able to decrypt the payload and verify the sender's signature.
- Case #3: The receiving application understands the protocol and is able to decrypt the payload and verify the sender's signature, but the timestamps fail the checks specified above under Checking of Timestamps (Section 6.9).
- Case #4: The receiving application understands the protocol and is able to decrypt the payload but is unable to verify the sender's signature.
- Case #5: The receiving application understands the protocol but is unable to decrypt the payload.
so for Case #1 π, the receiving app MUST do one and only one of these: (1) ignore the <e2e/> extension, (2) ignore the entire stanza, or (3) return a <service-unavailable/> error to the sender, as described in [XMPP-CORE]. pick one, not two, not zero π
Case #2 is the success case π, so the receiving app MUST NOT return a stanza error to the sender. no errors when everything went right, periodt β¨
Case #3 is where the timestamps went sideways β°. Here the receiving app MAY return a <not-acceptable/> error to the sender (as described in [XMPP-CORE]), and it can optionally add the app-specific <bad-timestamp/> condition element. here's what that looks like:
Example 16: Recipient returns <not-acceptable/> error:
<message from='romeo@example.net/orchard' type='chat'>
<e2e xmlns='urn:ietf:params:xml:ns:xmpp-e2e'>
[CDATA section here]
</e2e>
<error type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<bad-timestamp xmlns='urn:ietf:params:xml:xmpp-e2e'/>
</error>
</message>
Case #4 is when the signature can't be verified π΅οΈββοΈ. The receiving app SHOULD return a <not-acceptable/> error to the sender (as described in [XMPP-CORE]), and it can optionally add the <unverified-signature/> condition element. like this:
Example 17: Recipient returns <not-acceptable/> error:
<message from='romeo@example.net/orchard' type='chat'>
<e2e xmlns='urn:ietf:params:xml:ns:xmpp-e2e'>
[CDATA section here]
</e2e>
<error type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<unverified-signature xmlns='urn:ietf:params:xml:xmpp-e2e'/>
</error>
</message>
Case #5 is the decryption fail π. The receiving app SHOULD return a <bad-request/> error to the sender (as described in [XMPP-CORE]), and it can optionally add the <decryption-failed/> condition element. the example:
Example 18: Recipient returns <bad-request/> error:
<message from='romeo@example.net/orchard' type='chat'>
<e2e xmlns='urn:ietf:params:xml:ns:xmpp-e2e'>
[CDATA section here]
</e2e>
<error type='modify'>
<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<decryption-failed xmlns='urn:ietf:params:xml:xmpp-e2e'/>
</error>
</message>
8. Secure Communications Through a Gateway π
okay so a super common way for two totally different services to talk is a "gateway" π¦. it reads the protocol of one service and translates it into the protocol of the other. the CPIM specifications (specifically [MSGFMT] and [PIDF]) define the common profiles used for interoperability between instant messaging and presence services that comply with [IMP-REQS]. when an XMPP service talks to a non-XMPP service, it looks like this:
+-------------+ +-------------+ +------------+
| | | | | |
| XMPP | | XMPP-CPIM | | Non-XMPP |
| Service | <----> | Gateway | <----> | Service |
| | | | | |
+-------------+ +-------------+ +------------+
the end-to-end encryption method in this doc lets encrypted and/or signed instant messages and presence travel through an XMPP-CPIM gateway π. here's how the two directions work:
- When a gateway gets a secured XMPP message or presence stanza from the XMPP service, and it's addressed to a user on the non-XMPP service, the gateway MUST remove the XMPP "wrapper" (everything down to and including the
<e2e>and</e2e>tags) to reveal the multipart S/MIME object. then it routes that object to the non-XMPP service, wrapping it in that service's protocol first if needed π - When a gateway gets a secured non-XMPP instant message or presence document from the non-XMPP service, and it's addressed to a user on the XMPP service, the gateway MUST remove the non-XMPP "wrapper" (if there is one) to reveal the multipart S/MIME object. then it wraps the object in an XMPP message or presence "wrapper" (including the
<e2e>and</e2e>tags) and routes the XMPP stanza to the XMPP service πΈ
the wrapped S/MIME object MUST be immutable π§ and MUST NOT be modified by an XMPP-CPIM gateway. hands off, gateway π ββοΈ
9. urn:ietf:params:xml:xmpp-e2e Namespace π§
the <e2e xmlns='urn:ietf:params:xml:ns:xmpp-e2e'/> element is a wrapper for an XML CDATA section (see Section 2.7 of [XML]) π. inside it sits a "Message/CPIM", "application/pidf+xml", or "application/xmpp+xml" object. the urn:ietf:params:xml:xmpp-e2e namespace has no inherent semantics of its own, so the meaning of whatever's inside comes from one of these specs:
- [MSGFMT] for "Message/CPIM"
- [PIDF] for "application/pidf+xml"
- [XMPP-CORE] for "application/xmpp+xml"
the "application/xmpp+xml" media type is specified in this document, but the <xmpp/> element is just a wrapper for a <message/>, <presence/>, or <iq/> stanza. the semantics of those stanza types live in [XMPP-CORE] π
and since the urn:ietf:params:xml:ns:xmpp-e2e namespace has no inherent semantics and only specifies a using protocol, versioning is handled by the protocols that define the encapsulated objects ([MSGFMT], [PIDF], and [XMPP-CORE]) β¨
10. application/xmpp+xml Media Type π
the "application/xmpp+xml" media type follows the guidelines in [XML-MEDIA] π
. its root element is <xmpp/>. the root element MUST contain one and only one child element, which matches one of the XMPP stanza types (message, presence, or iq) when the default namespace is 'jabber:client' or 'jabber:server' as defined in [XMPP-CORE]. and the character encoding for this XML media type MUST be UTF-8, per Section 11.5 of [XMPP-CORE] π
11. Security Considerations π
okay bestie, this whole memo is about security, so this section is the big one π€. the detailed security considerations for instant messaging and presence protocols are in [IMP-REQS] (Sections 5.1 through 5.4), and the ones for XMPP specifically are in [XMPP-CORE] (Sections 12.1 through 12.6). on top of that, all of the security considerations in [XML-MEDIA] apply to the "application/xmpp+xml" media type.
the end-to-end security method here MAY result in secured instant messages and presence info going through a gateway that implements the CPIM specifications. and yes, that gateway MUST be compliant with the minimum security requirements of the instant messaging and presence protocols it talks to. no shortcuts, no cap π¨
12. IANA Considerations ποΈ
12.1. XML Namespace Name for e2e Data in XMPP π
so there's a URN sub-namespace for signed and encrypted content in the Extensible Messaging and Presence Protocol (XMPP) π«Ά. this namespace name follows the format in [XML-REG]. here's the registration:
URI: urn:ietf:params:xml:ns:xmpp-e2e
Specification: RFC 3923
Description: This is an XML namespace name of signed and encrypted
content for the Extensible Messaging and Presence Protocol as
defined by RFC 3923.
Registrant Contact: IESG, <iesg@ietf.org>
12.2. Content-type Registration for "application/xmpp+xml" π
this is the registration request for the media type, sent to ietf-types@iana.org. it's giving paperwork energy but it matters πΌ
To: ietf-types@iana.org
Subject: Registration of MIME media type application/xmpp+xml
MIME media type name: application
MIME subtype name: xmpp+xml
Required parameters: (none)
Optional parameters: (charset) Same as charset parameter of
application/xml as specified in RFC 3023; per Section 11.5 of
[XMPP-CORE], the charset must be UTF-8.
Encoding considerations: Same as encoding considerations of
application/xml as specified in RFC 3023; per Section 11.5 of
[XMPP-CORE], the encoding must be UTF-8.
Security considerations: All of the security considerations specified
in RFC 3023 and [XMPP-CORE] apply to this XML media type. Refer
to Section 11 of RFC 3923.
Interoperability considerations: (none)
Specification: RFC 3923
Applications which use this media type: XMPP-compliant instant
messaging and presence systems.
Additional information: (none)
Person and email address to contact for further information: IESG,
<iesg@ietf.org>
Intended usage: COMMON
Author/Change controller: IETF, XMPP Working Group
13. References π
13.1. Normative References πβ¨
okay so these are the docs the spec straight up needs you to have read, bestie π Every entry keeps its tag, so you can find it when the main text points at it.
- [CERT] Ramsdell, B., Ed., "Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.1 Certificate Handling", RFC 3850, July 2004.
- [CMS] Housley, R., "Cryptographic Message Syntax (CMS)", RFC 3852, July 2004.
- [CMS-AES] Schaad, J., "Use of the Advanced Encryption Standard (AES) Encryption Algorithm in Cryptographic Message Syntax (CMS)", RFC 3565, July 2003.
- [CMS-ALG] Housley, R., "Cryptographic Message Syntax (CMS) Algorithms", RFC 3370, August 2002.
- [CPIM] Peterson, J., "Common Profile for Instant Messaging (CPIM)", RFC 3860, August 2004.
- [CPP] Peterson, J., "Common Profile for Presence (CPP)", RFC 3859, August 2004.
- [DATETIME] Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, July 2002.
- [DISP] Troost, R., Dorner, S., and K. Moore, Ed., "Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field", RFC 2183, August 1997.
- [IMP-MODEL] Day, M., Rosenberg, J., and H. Sugano, "A Model for Presence and Instant Messaging", RFC 2778, February 2000.
- [IMP-REQS] Day, M., Aggarwal, S., Mohr, G., and J. Vincent, "Instant Messaging/Presence Protocol Requirements", RFC 2779, February 2000.
- [MSGFMT] Klyne, G. and D. Atkins, "Common Presence and Instant Messaging (CPIM): Message Format", RFC 3862, August 2004.
- [MULTI] Galvin, J., Murphy, S., Crocker, S., and N. Freed, "Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted", RFC 1847, October 1995.
- [PIDF] Sugano, H., Fujimoto, S., Klyne, G., Bateman, A., Carr, W., and J. Peterson, "Presence Information Data Format (PIDF)", RFC 3863, August 2004.
- [SMIME] Ramsdell, B., Ed., "Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.1 Message Specification", RFC 3851, July 2004.
- [TERMS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [XML-MEDIA] Murata, M., St. Laurent, S. and D. Kohn, "XML Media Types", RFC 3023, January 2001.
- [XMPP-CORE] Saint-Andre, P., Ed., "Extensible Messaging and Presence Protocol (XMPP): Core", RFC 3920, October 2004.
- [XMPP-IM] Saint-Andre, P., Ed., "Extensible Messaging and Presence Protocol (XMPP) Instant Messaging and Presence", RFC 3921, October 2004.
13.2. Informative References πΈ
these ones are just extra reading for the curious, not required to get the spec π§
- [CAPS] Hildebrand, J. and P. Saint-Andre, "Entity Capabilities", JSF JEP 0115, August 2004.
- [CMC] Myers, M., Liu, X., Schaad, J. and J. Weinstein, "Certificate Management Messages over CMS", RFC 2797, April 2000.
- [CMP] Adams, C. and S. Farrell, "Internet X.509 Public Key Infrastructure Certificate Management Protocols", RFC 2510, March 1999.
- [DISCO] Hildebrand, J., Millard, P., Eatmon, R. and P. Saint-Andre, "Service Discovery", JSF JEP 0030, July 2004.
- [MUC] Saint-Andre, P., "Multi-User Chat", JSF JEP 0045, June 2004.
- [XML] Bray, T., Paoli, J., Sperberg-McQueen, C. and E. Maler, "Extensible Markup Language (XML) 1.0 (3rd ed)", W3C REC-xml, February 2004,
<http://www.w3.org/TR/REC-xml>. - [XML-REG] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, January 2004.
Appendix A. Schema for urn:ietf:params:xml:ns:xmpp-e2e π
okay this schema is just for show, it's descriptive and NOT normative, so the real rules live in the main text π
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:ietf:params:xml:ns:xmpp-e2e'
xmlns='urn:ietf:params:xml:ns:xmpp-e2e'
elementFormDefault='qualified'>
<xs:element name='e2e' type='xs:string'/>
<xs:element name='decryption-failed' type='empty'/>
<xs:element name='signature-unverified' type='empty'/>
<xs:element name='bad-timestamp' type='empty'/>
<xs:simpleType name='empty'>
<xs:restriction base='xs:string'>
<xs:enumeration value=''/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Author's Address π¦
Peter Saint-Andre
Jabber Software Foundation
EMail: stpeter@jabber.org
Full Copyright Statement π
Copyright (C) The Internet Society (2004).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property π₯
the IETF doesn't take a side on whether any IPR claims around this tech are valid or how far they reach, and it hasn't gone looking for any either. the procedures for rights in IETF Documents are in BCP 78 and BCP 79.
IPR disclosures sent to the IETF Secretariat, any licence assurances, and the results of attempts to get a general licence or permission for implementers or users are available from the IETF online IPR repository at http://www.ietf.org/ipr.
the IETF also invites anyone to flag any copyrights, patents, patent applications, or other proprietary rights that might cover technology needed to implement this standard. send that info to the IETF at ietf-ipr@ietf.org. π«Ά
Acknowledgement π
funding for the RFC Editor function is currently provided by the Internet Society. π
π¦ where this page comes from
- ietf: rfc3923 2004-10
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms