diff options
| author | Linus Jahn <lnj@kaidan.im> | 2019-04-28 22:11:25 +0200 |
|---|---|---|
| committer | LNJ <lnj@kaidan.im> | 2019-09-06 21:18:51 +0200 |
| commit | e7394afc6730b16673f4173fcbc55d54a810a80b (patch) | |
| tree | 854b917a079c385e780a72f9465403b70d53dc57 /src/base | |
| parent | a0925867901052d97fe84c2fcf31c720e0443546 (diff) | |
| download | qxmpp-e7394afc6730b16673f4173fcbc55d54a810a80b.tar.gz | |
Implement XEP-0380: Explicit Message Encryption
This adds parsing and serialization for XEP-0380: Explicit Message
Encryption in version 0.3.0.
https://xmpp.org/extensions/xep-0380.html
Diffstat (limited to 'src/base')
| -rw-r--r-- | src/base/QXmppConstants.cpp | 10 | ||||
| -rw-r--r-- | src/base/QXmppConstants_p.h | 10 | ||||
| -rw-r--r-- | src/base/QXmppMessage.cpp | 105 | ||||
| -rw-r--r-- | src/base/QXmppMessage.h | 21 |
4 files changed, 145 insertions, 1 deletions
diff --git a/src/base/QXmppConstants.cpp b/src/base/QXmppConstants.cpp index b6fab47d..80c97b56 100644 --- a/src/base/QXmppConstants.cpp +++ b/src/base/QXmppConstants.cpp @@ -37,6 +37,8 @@ const char* ns_stanza = "urn:ietf:params:xml:ns:xmpp-stanzas"; const char* ns_rpc = "jabber:iq:rpc"; // XEP-0020: Feature Negotiation const char* ns_feature_negotiation = "http://jabber.org/protocol/feature-neg"; +// XEP-0027: Current Jabber OpenPGP Usage +const char* ns_legacy_openpgp = "jabber:x:encrypted"; // XEP-0030: Service Discovery const char* ns_disco_info = "http://jabber.org/protocol/disco#info"; const char* ns_disco_items = "http://jabber.org/protocol/disco#items"; @@ -135,6 +137,8 @@ const char* ns_chat_markers = "urn:xmpp:chat-markers:0"; const char* ns_csi = "urn:xmpp:csi:0"; // XEP-0363: HTTP File Upload const char* ns_http_upload = "urn:xmpp:http:upload:0"; +// XEP-0364: Current Off-the-Record Messaging Usage +const char* ns_otr = "urn:xmpp:otr:0"; // XEP-0367: Message Attaching const char* ns_message_attaching = "urn:xmpp:message-attaching:1"; // XEP-0369: Mediated Information eXchange (MIX) @@ -146,8 +150,14 @@ const char* ns_mix_node_participants = "urn:xmpp:mix:nodes:participants"; const char* ns_mix_node_presence = "urn:xmpp:mix:nodes:presence"; const char* ns_mix_node_config = "urn:xmpp:mix:nodes:config"; const char* ns_mix_node_info = "urn:xmpp:mix:nodes:info"; +// XEP-0373: OpenPGP for XMPP +const char* ns_ox = "urn:xmpp:openpgp:0"; +// XEP-0380: Explicit Message Encryption +const char* ns_eme = "urn:xmpp:eme:0"; // XEP-0382: Spoiler messages const char* ns_spoiler = "urn:xmpp:spoiler:0"; +// XEP-0384: OMEMO Encryption +const char* ns_omemo = "eu.siacs.conversations.axolotl"; // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements const char* ns_mix_pam = "urn:xmpp:mix:pam:1"; const char* ns_mix_roster = "urn:xmpp:mix:roster:0"; diff --git a/src/base/QXmppConstants_p.h b/src/base/QXmppConstants_p.h index 5304ada4..86003970 100644 --- a/src/base/QXmppConstants_p.h +++ b/src/base/QXmppConstants_p.h @@ -49,6 +49,8 @@ extern const char* ns_stanza; extern const char* ns_rpc; // XEP-0020: Feature Negotiation extern const char* ns_feature_negotiation; +// XEP-0027: Current Jabber OpenPGP Usage +extern const char* ns_legacy_openpgp; // XEP-0030: Service Discovery extern const char* ns_disco_info; extern const char* ns_disco_items; @@ -147,6 +149,8 @@ extern const char* ns_chat_markers; extern const char* ns_csi; // XEP-0363: HTTP File Upload extern const char* ns_http_upload; +// XEP-0364: Current Off-the-Record Messaging Usage +extern const char* ns_otr; // XEP-0367: Message Attaching extern const char* ns_message_attaching; // XEP-0369: Mediated Information eXchange (MIX) @@ -158,8 +162,14 @@ extern const char* ns_mix_node_participants; extern const char* ns_mix_node_presence; extern const char* ns_mix_node_config; extern const char* ns_mix_node_info; +// XEP-0373: OpenPGP for XMPP +extern const char* ns_ox; +// XEP-0380: Explicit Message Encryption +extern const char* ns_eme; // XEP-0382: Spoiler messages extern const char* ns_spoiler; +// XEP-0384: OMEMO Encryption +extern const char* ns_omemo; // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements extern const char* ns_mix_pam; extern const char* ns_mix_roster; diff --git a/src/base/QXmppMessage.cpp b/src/base/QXmppMessage.cpp index af4b2a6f..54ef4cd6 100644 --- a/src/base/QXmppMessage.cpp +++ b/src/base/QXmppMessage.cpp @@ -55,6 +55,24 @@ static const char* marker_types[] = { "acknowledged" }; +static const QStringList ENCRYPTION_NAMESPACES = { + QString(), + QString(), + ns_otr, + ns_legacy_openpgp, + ns_ox, + ns_omemo +}; + +static const QStringList ENCRYPTION_NAMES = { + QString(), + QString(), + QStringLiteral("OTR"), + QStringLiteral("Legacy OpenPGP"), + QStringLiteral("OpenPGP for XMPP (OX)"), + QStringLiteral("OMEMO") +}; + static const char *ns_xhtml = "http://www.w3.org/1999/xhtml"; enum StampType @@ -110,6 +128,10 @@ public: QString mixUserJid; QString mixUserNick; + // XEP-0380: Explicit Message Encryption + QString encryptionMethod; + QString encryptionName; + // XEP-0382: Spoiler messages bool isSpoiler = false; QString spoilerHint; @@ -123,7 +145,7 @@ public: /// \param thread QXmppMessage::QXmppMessage(const QString& from, const QString& to, const - QString& body, const QString& thread) + QString& body, const QString& thread) : QXmppStanza(from, to) , d(new QXmppMessagePrivate) { @@ -571,6 +593,74 @@ void QXmppMessage::setMixUserNick(const QString& mixUserNick) d->mixUserNick = mixUserNick; } +/// Returns the encryption method this message is advertised to be encrypted +/// with. +/// +/// \note QXmppMessage::NoEncryption does not necesserily mean that the message +/// is not encrypted; it may also be that the author of the message does not +/// support XEP-0380: Explicit Message Encryption. +/// +/// \note If this returns QXmppMessage::UnknownEncryption, you can still get +/// the namespace of the encryption with \c encryptionMethodNs() and possibly +/// also a name with \c encryptionName(). + +QXmppMessage::EncryptionMethod QXmppMessage::encryptionMethod() const +{ + if (d->encryptionMethod.isEmpty()) + return QXmppMessage::NoEncryption; + + int index = ENCRYPTION_NAMESPACES.indexOf(d->encryptionMethod); + if (index < 0) + return QXmppMessage::UnknownEncryption; + return static_cast<QXmppMessage::EncryptionMethod>(index); +} + +/// Advertises that this message is encrypted with the given encryption method. +/// See XEP-0380: Explicit Message Encryption for details. + +void QXmppMessage::setEncryptionMethod(QXmppMessage::EncryptionMethod method) +{ + d->encryptionMethod = ENCRYPTION_NAMESPACES.at(int(method)); +} + +/// Returns the namespace of the advertised encryption method via. XEP-0380: +/// Explicit Message Encryption. + +QString QXmppMessage::encryptionMethodNs() const +{ + return d->encryptionMethod; +} + +/// Sets the namespace of the encryption method this message advertises to be +/// encrypted with. See XEP-0380: Explicit Message Encryption for details. + +void QXmppMessage::setEncryptionMethodNs(const QString &encryptionMethod) +{ + d->encryptionMethod = encryptionMethod; +} + +/// Returns the associated name of the encryption method this message +/// advertises to be encrypted with. See XEP-0380: Explicit Message Encryption +/// for details. + +QString QXmppMessage::encryptionName() const +{ + if (!d->encryptionName.isEmpty()) + return d->encryptionName; + return ENCRYPTION_NAMES.at(int(encryptionMethod())); +} + +/// Sets the name of the encryption method for XEP-0380: Explicit Message +/// Encryption. +/// +/// \note This should only be used, if the encryption method is custom and is +/// not one of the methods listed in the XEP. + +void QXmppMessage::setEncryptionName(const QString &encryptionName) +{ + d->encryptionName = encryptionName; +} + /// Returns true, if this is a spoiler message according to XEP-0382: Spoiler /// messages. The spoiler hint however can still be empty. /// @@ -765,6 +855,10 @@ void QXmppMessage::parse(const QDomElement &element) } else if (xElement.tagName() == "mix" && xElement.namespaceURI() == ns_mix) { d->mixUserJid = xElement.firstChildElement("jid").text(); d->mixUserNick = xElement.firstChildElement("nick").text(); + // XEP-0380: Explicit Message Encryption + } else if (xElement.tagName() == "encryption" && xElement.namespaceURI() == ns_eme) { + d->encryptionMethod = xElement.attribute("namespace"); + d->encryptionName = xElement.attribute("name"); // XEP-0382: Spoiler messages } else if (xElement.tagName() == "spoiler" && xElement.namespaceURI() == ns_spoiler) { d->isSpoiler = true; @@ -923,6 +1017,15 @@ void QXmppMessage::toXml(QXmlStreamWriter *xmlWriter) const xmlWriter->writeEndElement(); } + // XEP-0380: Explicit Message Encryption + if (!d->encryptionMethod.isEmpty()) { + xmlWriter->writeStartElement("encryption"); + xmlWriter->writeAttribute("xmlns", ns_eme); + xmlWriter->writeAttribute("namespace", d->encryptionMethod); + helperToXmlAddAttribute(xmlWriter, "name", d->encryptionName); + xmlWriter->writeEndElement(); + } + // XEP-0382: Spoiler messages if (d->isSpoiler) { xmlWriter->writeStartElement("spoiler"); diff --git a/src/base/QXmppMessage.h b/src/base/QXmppMessage.h index 330c70fe..69e2d451 100644 --- a/src/base/QXmppMessage.h +++ b/src/base/QXmppMessage.h @@ -66,6 +66,18 @@ public: Acknowledged }; + /// This enum describes different end-to-end encryption methods. These can + /// be used to mark a message explicitly as encrypted with a specific + /// algothim. See XEP-0380: Explicit Message Encryption for details. + enum EncryptionMethod { + NoEncryption, ///< No encryption + UnknownEncryption, ///< Unknown encryption + OTR, ///< XEP-0364: Current Off-the-Record Messaging Usage + LegacyOpenPGP, ///< XEP-0027: Current Jabber OpenPGP Usage + OX, ///< XEP-0373: OpenPGP for XMPP + OMEMO ///< XEP-0384: OMEMO Encryption + }; + QXmppMessage(const QString& from = QString(), const QString& to = QString(), const QString& body = QString(), const QString& thread = QString()); @@ -151,6 +163,15 @@ public: QString mixUserNick() const; void setMixUserNick(const QString&); + // XEP-0380: Explicit Message Encryption + EncryptionMethod encryptionMethod() const; + void setEncryptionMethod(EncryptionMethod); + QString encryptionMethodNs() const; + void setEncryptionMethodNs(const QString&); + + QString encryptionName() const; + void setEncryptionName(const QString&); + // XEP-0382: Spoiler messages bool isSpoiler() const; void setIsSpoiler(bool); |
