RFC 3156 Update acknowledgements. Minior editorial fixes. Minior editorial fixes. Initial published version approved by the XMPP Council. First draft. This XMPP extension protocol specifies the foundations of
end-to-end encryption and authentication, based on digital
signatures, of data with the help of OpenPGP. Additional XEPs will
use this extension protocol as building block when specifying their
own OpenPGP profile suiting their use case. One such profile is the
Instant Messaging Profile specified in &xep0374;. XMPP provides the mechanisms to solve a lot of issues that come
with modern day OpenPGP usage. For example, based on &xep0163; this
specification describes a standardized way to discover OpenPGP
public keys of other entities. But unlike the OpenPGP keyservers,
this process establishes a strong relation between the key and the
key's owning entity (usually a human user). A similar mechanism
described herein allows to synchronize the secret key(s) across
multiple devices. OpenPGP in return allows for end-to-end encrypted data to be
exchanged between one, two or even multiple entities
(multi-end-to-multi-end encryption). Therefore this XEP can be used
for example to implement end-to-end encrypted &xep0045;. The &openpgp; extension element qualified by the
'urn:xmpp:openpgp:0' namespace is used in order to exchange
encrypted and signed data. The text content of &openpgp; ("BASE64_OPENPGP_MESSAGE") is a
Base64 encoded (&rfc4648; § 4)
OpenPGP message as specified in &rfc4880; which contains an
encrypted and/or signed UTF-8 (&rfc3629;) encoded string. This
string MUST correspond to exactly one OpenPGP content element,
that is, it represents either a &signcrypt;, a &sign; or a &crypt;
extension element qualified by the 'urn:xmpp:openpgp:0'
namespace. Note that OpenPGP's ASCII Armor is not used, instead
the XMPP client MUST encode the raw bytes of OpenPGP message using
Base64. In case of a &signcrypt; element, the OpenPGP message embedded
in the &openpgp; element MUST be encrypted and signed, and SHOULD
also be encrypted to self. In case of a &sign; element, the
OpenPGP message MUST be signed and MUST NOT be encrypted. In case
of &crypt; the OpenPGP message MUST NOT be signed, but MUST be
encrypted. OpenPGP content elements MUST possess exactly one 'time'
element as direct child elements. The &signcrypt; and &crypt;
content elements MUST contain at least one 'to' element(s), which
MUST have a 'jid' attribute containing the intended recipient's
XMPP address of the signed and/or encrypted data to prevent
Surreptitious Forward Attacks OpenPGP content elements MUST possess exactly one &payload;
element. The child elements of &payload; can be seen as OpenPGP
secured Stanza extension elements which are encrypted and/or
signed. After the &openpgp; element and the including &signcrypt;,
&sign; or &crypt; element was verified, they are processed
according to the specification of the relevant OpenPGP for XMPP
profile (see for example &xep0374;). Recipients MUST verify that the signature is valid, that the
signature's key corresponds to the sender's key, and that the
sender's key has a User ID containing the sender's XMPP
address in the form "xmpp:juliet@example.org" (for details see
"OpenPGP User IDs"). Thus,
the recipient may
need to retrieve the key from the Personal Eventing Protocol node
as described above. At least one of the XMPP addresses found in
the 'to' elements contained in OpenPGP content element MUST
correspond to the outer 'to' of the XMPP &MESSAGE;. Furthermore,
recipients are RECOMMENDED to verify the 'time' element for
plausibility or to display it to a user for verification. Parties interested in exchanging encrypted data between each
other via OpenPGP need to know the public key(s) of the
recipients. The following section specifies a mechanism to announce
and discover public keys. In order to announce the public key, the client needs to store
it in a PEP node. The public key data, as specified in RFC
4880, is stored within a <pubkey/> element which is a
child element of the <pubkeys/> element qualified by the
'urn:xmpp:openpgp:0' namespace. Note that OpenPGP's ASCII Armor is
not used, instead the XMPP client MUST encode the public key using
Base64. Client SHOULD only try to store the public key if the
Personal Eventing Protocol service supports persistent-items, thus
it SHOULD check if the service reports the
'http://jabber.org/protocol/pubsub#persistent-items' feature. In order to discover the public key of an XMPP entity, clients
send a PubSub &IQ; request to the entity's bare JID of which it
wants to know the public key. Note that the result may contain multiple pubkey elements. Only
the public keys found in the most recent MUST be used. Requesters
may want to limit the results to the most recent item using the
'max_items' attribute set to '1'. Clients could alternatively use
&xep0059; as an alternative to 'max_items' but accoding to
XEP-0060 RSM is not (yet) mandatory for PubSub
services. Some XMPP services may not provide the Personal Eventing
Protocol feature required to provide the mechanism described
here. If so, they will return an &IQ; error of type
service-unavailable. A private PEP node is used to allow XMPP clients to synchronize
the user's secret OpenPGP key. Where private PEP node is defined: A
PEP node in whitelist mode where only the bare JID of the key
owner is whitelisted as described in &xep0223;. The secret key is
additionally encrypted. The used PEP server MUST support PEP and the whitelist access
model. It SHOULD also support persistent items. The service discovery result must contain a PEP identity
'<identity category='pubsub' type='pep'/>, and the
'http://jabber.org/protocol/pubsub#access-whitelist'
feature. Ideally it also contains the
'http://jabber.org/protocol/pubsub#persistent-items'
feature In order to synchronize the secret key over a private PEP node,
clients first need to discover and verify the node for the correct
settings. If the node does not exist the service will return an &IQ;
error indicating the item-not-found error condition. The
client MUST then create it with an whitelist access model. The service will return a service-unavailable error &IQ; if
it does not support PEP. The node is now created and the only affiliated entity is the
bare JID of the user, who created the node, with an affiliation as
'owner'. In order to set a new secret key, clients store the encrypted
secret key as Base64 encoded raw OpenPGP message within an
<secretkey/> element qualified by the 'urn:xmpp:openpgp:0'
namespace. These secret key backups are created as follows: Implementations of this XEP MUST generate and accept only
version 4 (or higher) OpenPGP packets. Lower version OpenPGP
packets are insecure in many aspects (see for example RFC
4880 §
5.5.2.). OpenPGP implementations have a sad history of being not very
user-friendly which results in users either not using OpenPGP or in
users wrongly using OpenPGP. Implementors of this XEP, and
additional future XEPs based on this XEP, therefore should read
STEED Furthermore implementors should design the user interface for
effective security by following the design principles and
techniques for security mentioned in "Why Johnny Can't
Encrypt". Implementors should be aware that the size OpenPGP public and
secret keys is somewhere in the range of tens of
kilobytes. Applying Base64 encoding on keys, as it is described
herein, further increases the size. The formula to determine the
Base64 encoded size is: ceil(bytes / 3) * 4. Thus the lower bound
for the maximum stanza size of 10000 bytes, as specified in RFC
6120 § 13.12. 4., is usually exceeded. However all XMPP server
implementations, the authors are aware of, follow the
recommendation of the RFC and do not blindly set the maximum
stanza size to such a low value, but use a much higher
threshold. Therefore, this should hardly be an issue for
implementations. Nevertheless, it is advised to keep the size of
OpenPGP keys small by removing all signatures except the most
recent self-signature on each User ID before exporting the key
(cf. GnuPG's --export-options export-minimal).
In addition, implementors are advised to handle
<policy-violation/> error responses when trying to
transmit Base64 encoded keys. The format of XMPP addresses, sometimes called JIDs, is well
defined. Thus they need to be normalized, as defined in
&rfc7622;. When implementations are required to compare XMPP
addresses for equality, as it is the case in "Verification of &openpgp;
Content", then they also have to compare the normalized
versions of the addresses. This specification intentionally does not specify if the used
OpenPGP key should be a primary key or a subkey. It is even
possible to announce multiple public keys in the Personal Eventing
Protocol node. Implementations MUST be prepared to find multiple
public keys. The authors however believe that for ease of use only
one OpenPGP key specially crafted for the XMPP use case should be
created, announced and used. The &openpgp; and OpenPGP content elements are container
elements for arbitrary signed and encrypted data and can thus act
as building blocks for encrypted data included in Message, IQ and
Presence stanzas. For example, future specifications may use them
to implement encrypted versions of &xep0047; or &xep0261;. Note that signed OpenPGP messages already contain a timestamp
as per the OpenPGP specification. OpenPGP content elements
nevertheless require the 'time' element because not every OpenPGP
API may provide access to the embedded OpenPGP timestamp. The 'rpad' element of the OpenPGP content elements exists to
prevent length-based side channel attacks. This specification addresses all relevant issues of &xep0027;
(§
4, §
5). It mitigates replay attacks by including the
recipient's address and a timestamp in the OpenPGP content
element Features like signed presences, which is provided by XEP-0027,
may be added later on as add-on XEP to this. We decided against OpenPGP ASCII Armor (which contains an
additional checksum) and in favor for Base64, because
encoding should be part of the network application rather than the
crypto layer. Also XMPP, needs no additional error correction of payload.
In "MIME Security with OpenPGP" (&rfc3156;), ASCII Armor
has only been chosen to be backwards compatible with legacy applications
supporting non-MIME OpenPGP emails only. OpenPGP User IDs normally consist of a name - email address pair, e.g.,
"Juliet <juliet@example.org>" (RFC 4880 § 5.11).
For this XEP, we require User IDs of the format "xmpp:juliet@example.org".
First, it is required to have at least one User ID indicating the use
of this OpenPGP key. When doing certification of keys (key signing),
the partner must know what User ID she actually certifies.
Second, this format uses the standardized URI from XEP-0147 to indicate
that this User ID corresponds to a key that is used for XMPP.
Third, having the Real Name inside provides no additional security
or guideline if this key should be certified. The XMPP address
is the only trust anchor here. The scope of this XEP is intentionally limited, so that the
specification just defines way for XMPP entities to discover,
announce and synchronize OpenPGP keys, and how to exchange signed
and encrypted data between two or more parties. Everything else is
outside its scope. For example, how 'secure' the key material is
protected on the endpoints is up to the implementation. And while this XEP specifies a mechanism how to discover and
retrieve a public key, it does not define how the trust relation to
this key should be established. Even if key discovery and retrieval
over XMPP provides a stronger coupling between the possessing entity
(the XMPP address) and the key, as compared to the OpenPGP keyservers,
how a XMPP server authenticates a remote server is a server policy,
which does vary from server to server. Implementation MUST provide a
way for the user to establish and assign trust to a public key. For
example by using a QR code shown on the recipient's device screen. Besides the protocol defined herein, OpenPGP implementations are
another big attack surface. Needless to say that the security of
encrypted data exchanged using this protocol depends on the security
of the used OpenPGP implementation. It is strongly RECOMMENED to use
existing implementations instead of writing your own. OpenPGP
implementations have suffered from various vulnerabilities in the past
which opened up DoS attack vectors. For example CVE-2013-4402
and CVE-2014-4717. This document requires no interaction with &IANA;. The ®ISTRAR; includes 'urn:xmpp:openpgp:0' in its registry of protocol namespaces (see &NAMESPACES;). TODO: Add after the XEP leaves the 'experimental' state. Thanks to Emmanuel Gil Peyrot, Sergei Golovan, Marc Laporte, Georg
Lukas, Adithya Abraham Philip and Brian Cully for their feedback. The first draft of this specification was worked out and written
on the wall of the 'Kymera' room in one of Google's buildings by the
authors, consisting of members of the XMPP Standards Foundation and
the OpenKeychain project, at the GSOC Mentors Summit 2015. The
authors would like to thank Google for making it possible by
bringing the right people together.
Content Element
'to' Element
'time' Element
<rpad/> Element
<payload/> Element
&signcrypt;
MUST have at least one
MUST have exactly one
SHOULD have exaclty one
MUST have exactly one
&sign;
MAY NOT contain one
MUST have exaclty one
NOT REQUIRED
MUST have exactly one
&crypt;
MUST have at least one
MUST have exaclty one
SHOULD have exaclty one
MUST have exactly one