XEP-0473: OpenPGP for XMPP Pubsub

Abstract
Specifies an OpenPGP for XMPP (XEP-0373) profile for the pubsub use case.
Author
Jérôme Poisson
Copyright
© 2022 – 2022 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status

Experimental

WARNING: This Standards-Track document is Experimental. Publication as an XMPP Extension Protocol does not imply approval of this proposal by the XMPP Standards Foundation. Implementation of the protocol described herein is encouraged in exploratory implementations, but production systems are advised to carefully consider whether it is appropriate to deploy implementations of this protocol before it advances to a status of Draft.
Type
Standards Track
Version
0.1.0 (2022-12-13)
Document Lifecycle
  1. Experimental
  2. Proposed
  3. Stable
  4. Final

1. Introduction

Publish-Subscribe (XEP-0060) [1] and Personal Eventing Protocol (XEP-0163) [2] are widely used XMPP features. However, items are published in plain text, making them readable by server administrators or anybody having administrator level access on the pubsub/PEP services.

Although this is not a problem for data intended to be published publicly, there are many cases where it may be desirable to make the data inaccessible to anybody but the selected recipients, or in other words to end-to-end encrypt the data.

This specification aims to provide an easy way to e2e encrypt items of a pubsub node, and to share access with other entities. It is compatible with all existing pubsub/PEP features, which makes it possible to use securily features such a geolocation, private blogs, private calendar events, data forms, etc.

2. Requirements

The design goals of this XEP are:

3. Glossary

4. Overview

To encrypt a pubsub node, each item is symmetrically encrypted with a shared secret using OpenPGP symmetric encryption. The secret is shared with other entities using e2e encrypted messages with OpenPGP for XMPP (XEP-0373) [3]. If an entity's access is revoked or a shared secret may have been compromised, a new shared secret is generated and new items are encrypted with it.

5. Use Cases

5.1 Encrypting Pubsub Item

Juliet wants to create a private blog (using Microblogging Over XMPP (XEP-0277) [4]) that she only share with her confidante and her lover. To make sure that her family, who manages her XMPP server, can't read the content, she want to use end-to-end encryption.

To do so, her client creates a "shared secret" by generating a cryptographically strong key that will be used to symmetrically encrypt new items. This key MUST be associated with an ID, which MUST be an unique sequence of characters usable in an XML attribute. She will later share this key with entities allowed to access or publish on the blog as explained below.

From now on, all items that Juliet publishes on the node SHOULD be symmetrically encrypted with the shared secret by using OpenPGP symmetric encryption.

To publish an encrypted item, an <encrypted/> element qualified by the 'urn:xmpp:openpgp:pubsub:0' namespace MUST be used as payload. This element MUST contain a 'secret' attribute whose value is the ID of the shared secret used. The content of the element is a base64 encoded Symmetric-Key Encrypted Session Key Packet as specified at RFC 4880 [5] § 5.3 (in a similar way as secret key backup is encoded in XEP-0373). The encrypted content is the item payload that would normally be used.

The encrypted node SHOULD have a "whitelist" access model as specified in Publish-Subscribe (XEP-0060) [1]. Juliet's client ensure that either by creating a new node with suitable access model, or by changing the access model of existing node.

Example 1. Juliet publish an encrypted item
<iq
  type='set'
  from='juliet@capulet.lit/chamber'
  to='pubsub.capulet.lit'
  id='encrypted1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='123abc'>
      <item id="encrypt_123">
        <encrypted xmlns='urn:xmpp:openpgp:pubsub:0' key='1234-abcd-5678-efgh'>
          <!-- BASE64_OPENPGP_SYMMETRICALLY_ENCRYPTED_ITEM -->
        </encrypted>
      </item>
    </publish>
  </pubsub>
</iq>

5.2 Transmit Shared Secret

Now that Juliet has started to publish encrypted items on a blog, she wants to share the secret key with her confidante and her lover. To do so she uses a e2ee <message/> stanza by using an <openpgp/> element wrapping a <signcrypt/> as specified in XEP-0373 "Exchanging OpenPGP Encrypted and Signed Data". The encrypted payload of the <signcrypt/> MUST contain a <shared-secret/> element qualified by the 'urn:xmpp:openpgp:pubsub:0' namespace. This element MUST have the following attributes:

The <shared-secret/> SHOULD have a 'type' attribute whose value is the pubsub#type that the node would have if it were plain text (i.e. the semantic type information of decrypted data in the node, usually the namespace of the decrypted payload).

The content of the <shared-secret/> element MUST be the shared secret (i.e. the passphrase used to symmetrically encode items).

She send messages with the encrypted shared secret to her nurse, Romeo and herself (so her other devices get the shared secret too).

Entities MUST always use the most recently generated shared secret to encrypt new items (the 'timestamp' attribute is used to check generation date and time).

Following example only show the <shared-secret/> element, as it is normally put as an encrypted payload of OpenPGP for XMPP (XEP-0373) [3] <signcrypt/> payload.

Example 2. shared-secret element (normally encrypted as part of XEP-0373's signcrypt payload)
  <shared-secret
    xmlns='urn:xmpp:openpgp:pubsub:0'
    jid='pubsub.capulet.lit'
    node='123abc'
    id='1234-abcd-5678-efgh'
    timestamp='2022-10-10T13:24:31Z'
    type='http://www.w3.org/2005/Atom'
    >
    ZSRD5lK9mz-5VHNyu2N1XLiJZ8I87jkv85ceZkVrOGA
  </shared-secret>
  

note: we use <message/> instead of PEP or Pubsub to transmit the shared secret for several reasons:

5.3 Revocation and Shared Secret Rotation

If there is any doubt about the compromise of a shared secret or if access to the encrypted node is revoked for an entity, the shared secret SHOULD BE rotated.

To rotate a key, a <message/> must be sent to all people which got the shared secret. The <message/> MUST contain a XEP-0373 <openpgp/> element with a <signcrypt/> element whose payload is an encrypted <revoke/> element qualified by the 'urn:xmpp:openpgp:pubsub:0' namespace, which MUST have a 'jid' attribute whose value is the JID of the pubsub/PEP service where the node is, a 'node' attribute whose value is the name of the node, and an 'id' attribute whose value is the shared secret ID.

Optionally, the <revoke/> element MAY have one or more <reason/> child element(s) which contain a human readable message explaining the reason of the revocation. The <reason/> element MAY contain an 'xml:lang' attribute with the language code of the text, and there MAY be several <reason/> elements if and only if they have distinct xml:lang. A revoked key MUST NOT be used to encrypt new items.

Then a new shared secret MUST be generated and transmitted to all participants (excluding those who have seen their access revoked) as explained in Transmit Shared Secret.

Note that if an entity's access is revoked, it SHOULD also be removed from the node's whitelist (if "whitelist" has been used as access model as recommended).

Following example only show the <revoke/> element, as it is normally put as an encrypted payload of OpenPGP for XMPP (XEP-0373) [3] <signcrypt/> payload.

Example 3. revoke element (normally encrypted as part of XEP-0373's signcrypt payload)
  <revoke xmlns='urn:xmpp:openpgp:pubsub:0' jid='pubsub.capulet.lit' node='123abc' id='1234-abcd-5678-efgh'>
    <reason>Revoked access from an entity</reason>
  </revoke>
  

Items published before the key rotation SHOULD NOT be re-encrypted as it would be resource intensive, and revoked entities may have made a copy anyway.

When access to the shared secret is granted to a new entity, all previously used keys SHOULD be transmitted (with their 'revoked' attribute set to "true" as explained in Transmit Shared Secret.) along with the currently used shared secret. This allows the new entity to decrypt the items encrypted with the old keys. The <shared-secret/> elements can either be sent in the same encrypted payload of a single <message/>, or split into multiple encrypted <message/>, it's up to the implementation to decide which is better (keep in mind that too many shared secrets in a single message may reach the maximum stanza size limit at some point, even if this limit is not likely to be reached for most usual cases).

6. Business Rules

The shared secret and revocation SHOULD be generated by node owner.

<message/> with encrypted <shared-secret/> or <revoke/> elements MUST be sent to everybody who must have access to the node. At least one of the encrypted payload SHOULD be encrypted for the sender themselves (either by sending the <message/> directly to the sender, or to decrypt a copy received with Message Carbons (XEP-0280) [7]), so other devices of the sender can get the shared secret too.

When Pubsub Attachments (XEP-0470) [8] are used, the attachment node SHOULD have the same access model (i.e. whitelist as recommended in Security Considerations) as the encrypted node, with authorized entities synchronized (this should be done automatically for fully compliant services). The items published to attachment node itself MUST be encrypted using this protocol. Due to validity check of attachment items, the encrypted element MUST be a child of a XEP-0470's <attachments/> element, instead of being the <item/> payload as usual. Note that this will prevent the summary feature to work with encrypted elements, and the end-user client will have to do the summary itself, this is an inevitable trade-off when using e2ee.

The "pubsub#type" of an encrypted item is always "urn:xmpp:openpgp:pubsub:0", thus no information is leaked on the content of the node, and all encrypted nodes can easily be retrieved by using PubSub Type Filtering (XEP-0462) [9].

Note that encrypted items MAY be mixed with plain text items: for instance if a blog is public, but some of its items are private. However the proper handling of this use case is out of scope of this specification.

7. Implementation Notes

This specification uses OpenPGP for XMPP (XEP-0373) [3] independently of OpenPGP for XMPP Instant Messaging (XEP-0374) [10], implementations SHOULD avoid double encryption (e.g. by excluding <openpgp/> element qualified by 'urn:xmpp:openpgp:0' namespace from encryption by XEP-0374 implementation), and MUST ensure that element is correctly decrypted. Double encryption should be checked, and the <openpgp/> element MUST be decrypted even if OXIM (XEP-0374) is not being used.

8. Discovering Support

If a client supports the protocol specified in this XEP, it MUST advertise it by including the "urn:xmpp:openpgp:pubsub:0" discovery feature in response to a Service Discovery (XEP-0030) [11] information request:

Example 4. Service Discovery information request
<iq type='get'
    from='juliet@example.org/balcony'
    to='romeo@example.org/orchard'
    id='disco1'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
Example 5. Service Discovery information response
<iq type='result'
    from='romeo@example.org/orchard'
    to='juliet@example.org/balcony'
    id='disco1'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    ...
    <feature var='urn:xmpp:openpgp:pubsub:0'/>
    ...
  </query>
</iq>

9. Security Considerations

10. IANA Considerations

TODO

11. XMPP Registrar Considerations

TODO

12. XML Schema

TODO

13. Acknowledgements

Thanks to Tim Henkes for his advices and NLNet foundation/NGI0 Discovery for funding.


Appendices

Appendix A: Document Information

Series
XEP
Number
0473
Publisher
XMPP Standards Foundation
Status
Experimental
Type
Standards Track
Version
0.1.0
Last Updated
2022-12-13
Approving Body
XMPP Council
Dependencies
XMPP Core, XEP-0001, XEP-0004, XEP-0060, XEP-0373
Supersedes
None
Superseded By
None
Short Name
oxps
Source Control
HTML

This document in other formats: XML  PDF

Appendix B: Author Information

Jérôme Poisson
Email
goffi@goffi.org
JabberID
goffi@jabber.fr

Copyright

This XMPP Extension Protocol is copyright © 1999 – 2024 by the XMPP Standards Foundation (XSF).

Permissions

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.

Disclaimer of Warranty

## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. ##

Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.

IPR Conformance

This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which can be found at <https://xmpp.org/about/xsf/ipr-policy> or obtained by writing to XMPP Standards Foundation, P.O. Box 787, Parker, CO 80134 USA).

Visual Presentation

The HTML representation (you are looking at) is maintained by the XSF. It is based on the YAML CSS Framework, which is licensed under the terms of the CC-BY-SA 2.0 license.

Appendix D: Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 6120) and XMPP IM (RFC 6121) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Appendix E: Discussion Venue

The primary venue for discussion of XMPP Extension Protocols is the <standards@xmpp.org> discussion list.

Discussion on other xmpp.org discussion lists might also be appropriate; see <https://xmpp.org/community/> for a complete list.

Errata can be sent to <editor@xmpp.org>.

Appendix F: Requirements Conformance

The following requirements keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".

Appendix G: Notes

1. XEP-0060: Publish-Subscribe <https://xmpp.org/extensions/xep-0060.html>.

2. XEP-0163: Personal Eventing Protocol <https://xmpp.org/extensions/xep-0163.html>.

3. XEP-0373: OpenPGP for XMPP <https://xmpp.org/extensions/xep-0373.html>.

4. XEP-0277: Microblogging over XMPP <https://xmpp.org/extensions/xep-0277.html>.

5. RFC 4880: OpenPGP Message Format <http://tools.ietf.org/html/rfc4880>.

6. XEP-0082: XMPP Date and Time Profiles <https://xmpp.org/extensions/xep-0082.html>.

7. XEP-0280: Message Carbons <https://xmpp.org/extensions/xep-0280.html>.

8. XEP-0470: Pubsub Attachments <https://xmpp.org/extensions/xep-0470.html>.

9. XEP-0462: PubSub Type Filtering <https://xmpp.org/extensions/xep-0462.html>.

10. XEP-0374: OpenPGP for XMPP Instant Messaging <https://xmpp.org/extensions/xep-0374.html>.

11. XEP-0030: Service Discovery <https://xmpp.org/extensions/xep-0030.html>.

Appendix H: Revision History

Note: Older versions of this specification might be available at https://xmpp.org/extensions/attic/

  1. Version 0.1.0 (2022-12-13)
    Accepted by vote of Council on 2022-10-19.
    XEP Editor (jsc)
  2. Version 0.0.6 (2022-10-12)
    jp
  3. Version 0.0.5 (2022-10-12)
    jp
  4. Version 0.0.4 (2022-10-11)
    jp
  5. Version 0.0.3 (2022-10-10)
    jp
  6. Version 0.0.2 (2022-10-10)

    Remove useless references to XEP-0374 + acknowledgements

    jp
  7. Version 0.0.1 (2022-10-09)

    First draft.

    jp

Appendix I: Bib(La)TeX Entry

@report{poisson2022oxps,
  title = {OpenPGP for XMPP Pubsub},
  author = {Poisson, Jérôme},
  type = {XEP},
  number = {0473},
  version = {0.1.0},
  institution = {XMPP Standards Foundation},
  url = {https://xmpp.org/extensions/xep-0473.html},
  date = {2022-10-09/2022-12-13},
}

END