aboutsummaryrefslogtreecommitdiff
path: root/src/base/QXmppOmemoData.cpp
diff options
context:
space:
mode:
authorMelvin Keskin <melvo@olomono.de>2021-09-02 23:35:11 +0200
committerLinus Jahn <lnj@kaidan.im>2021-09-03 16:16:14 +0200
commit11db6293ced5c4665630ad3d728aba5751a3f658 (patch)
tree93e8536de8daa881d8ee84b28b7bc5e0a3571572 /src/base/QXmppOmemoData.cpp
parent2ccc8d2d7033bb7180638ec8f980b904cfe3d686 (diff)
downloadqxmpp-11db6293ced5c4665630ad3d728aba5751a3f658.tar.gz
Add QXmppOmemoDeviceBundle
Co-authored-by: Germán Márquez Mejía <mancho@olomono.de>
Diffstat (limited to 'src/base/QXmppOmemoData.cpp')
-rw-r--r--src/base/QXmppOmemoData.cpp234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/base/QXmppOmemoData.cpp b/src/base/QXmppOmemoData.cpp
index b095ac24..84170c24 100644
--- a/src/base/QXmppOmemoData.cpp
+++ b/src/base/QXmppOmemoData.cpp
@@ -23,11 +23,13 @@
*/
#include "QXmppConstants_p.h"
+#include "QXmppOmemoDeviceBundle.h"
#include "QXmppOmemoDeviceElement.h"
#include "QXmppOmemoDeviceList.h"
#include "QXmppUtils.h"
#include <QDomElement>
+#include <QMap>
///
/// \class QXmppOmemoDeviceElement
@@ -231,3 +233,235 @@ bool QXmppOmemoDeviceList::isOmemoDeviceList(const QDomElement &element)
return element.tagName() == QStringLiteral("devices") &&
element.namespaceURI() == ns_omemo_1;
}
+
+///
+/// \class QXmppOmemoDeviceBundle
+///
+/// \brief The QXmppOmemoDeviceBundle class represents an OMEMO bundle as
+/// defined by \xep{0384, OMEMO Encryption}.
+///
+/// It is a collection of publicly accessible data used by the X3DH key exchange.
+/// The data is used to build an encrypted session with an OMEMO device.
+///
+/// \since QXmpp 1.5
+///
+
+class QXmppOmemoDeviceBundlePrivate : public QSharedData
+{
+public:
+ QByteArray publicIdentityKey;
+ QByteArray signedPublicPreKey;
+ uint32_t signedPublicPreKeyId = 0;
+ QByteArray signedPublicPreKeySignature;
+ QMap<uint32_t, QByteArray> publicPreKeys;
+};
+
+///
+/// Constructs an OMEMO device bundle.
+///
+QXmppOmemoDeviceBundle::QXmppOmemoDeviceBundle()
+ : d(new QXmppOmemoDeviceBundlePrivate)
+{
+}
+
+///
+/// Constructs a copy of \a other.
+///
+/// \param other
+///
+QXmppOmemoDeviceBundle::QXmppOmemoDeviceBundle(const QXmppOmemoDeviceBundle &other) = default;
+
+QXmppOmemoDeviceBundle::~QXmppOmemoDeviceBundle() = default;
+
+///
+/// Assigns \a other to this OMEMO device bundle.
+///
+/// \param other
+///
+QXmppOmemoDeviceBundle &QXmppOmemoDeviceBundle::operator=(const QXmppOmemoDeviceBundle &other) = default;
+
+///
+/// Returns the public identity key.
+///
+/// The public identity key is the public long-term key which never changes.
+///
+/// \return the public identity key
+///
+QByteArray QXmppOmemoDeviceBundle::publicIdentityKey() const
+{
+ return d->publicIdentityKey;
+}
+
+///
+/// Sets the public identity key.
+///
+/// \param key public identity key
+///
+void QXmppOmemoDeviceBundle::setPublicIdentityKey(const QByteArray &key)
+{
+ d->publicIdentityKey = key;
+}
+
+///
+/// Returns the public pre key that is signed.
+///
+/// \return the signed public pre key
+///
+QByteArray QXmppOmemoDeviceBundle::signedPublicPreKey() const
+{
+ return d->signedPublicPreKey;
+}
+
+///
+/// Sets the public pre key that is signed.
+///
+/// \param key signed public pre key
+///
+void QXmppOmemoDeviceBundle::setSignedPublicPreKey(const QByteArray &key)
+{
+ d->signedPublicPreKey = key;
+}
+
+///
+/// Returns the ID of the public pre key that is signed.
+///
+/// The ID is 0 if it is unset.
+///
+/// \return the ID of the signed public pre key
+///
+uint32_t QXmppOmemoDeviceBundle::signedPublicPreKeyId() const
+{
+ return d->signedPublicPreKeyId;
+}
+
+///
+/// Sets the ID of the public pre key that is signed.
+///
+/// A valid ID must be at least 1 and at most 2^32-1.
+///
+/// \param id ID of the signed public pre key
+///
+void QXmppOmemoDeviceBundle::setSignedPublicPreKeyId(const uint32_t id)
+{
+ d->signedPublicPreKeyId = id;
+}
+
+///
+/// Returns the signature of the public pre key that is signed.
+///
+/// \return the signature of the signed public pre key
+///
+QByteArray QXmppOmemoDeviceBundle::signedPublicPreKeySignature() const
+{
+ return d->signedPublicPreKeySignature;
+}
+
+///
+/// Returns the signature of the public pre key that is signed.
+///
+/// \param signature signature of the signed public pre key
+///
+void QXmppOmemoDeviceBundle::setSignedPublicPreKeySignature(const QByteArray &signature)
+{
+ d->signedPublicPreKeySignature = signature;
+}
+
+///
+/// Returns the public pre keys.
+///
+/// The key of a key-value pair represents the ID of the corresponding public
+/// pre key.
+/// The value of a key-value pair represents the public pre key.
+///
+/// \return the public pre keys
+///
+QMap<uint32_t, QByteArray> QXmppOmemoDeviceBundle::publicPreKeys() const
+{
+ return d->publicPreKeys;
+}
+
+///
+/// Sets the public pre keys.
+///
+/// The key of a key-value pair represents the ID of the corresponding public
+/// pre key.
+/// The ID must be at least 1 and at most 2^32-1, otherwise the corresponding
+/// key-value pair is ignored.
+/// The value of a key-value pair represents the public pre key.
+///
+/// \param keys public pre keys
+///
+void QXmppOmemoDeviceBundle::setPublicPreKeys(const QMap<uint32_t, QByteArray> &keys)
+{
+ for (auto it = keys.cbegin(); it != keys.cend(); it++) {
+ if (it.key() > 0) {
+ d->publicPreKeys.insert(it.key(), it.value());
+ }
+ }
+}
+
+/// \cond
+void QXmppOmemoDeviceBundle::parse(const QDomElement &element)
+{
+ d->publicIdentityKey = QByteArray::fromBase64(element.firstChildElement(QStringLiteral("ik")).text().toLatin1());
+
+ const auto signedPublicPreKeyElement = element.firstChildElement(QStringLiteral("spk"));
+ if (!signedPublicPreKeyElement.isNull()) {
+ d->signedPublicPreKeyId = signedPublicPreKeyElement.attribute(QStringLiteral("id")).toInt();
+ d->signedPublicPreKey = QByteArray::fromBase64(signedPublicPreKeyElement.text().toLatin1());
+ }
+ d->signedPublicPreKeySignature = QByteArray::fromBase64(element.firstChildElement(QStringLiteral("spks")).text().toLatin1());
+
+ const auto publicPreKeysElement = element.firstChildElement(QStringLiteral("prekeys"));
+ if (!publicPreKeysElement.isNull()) {
+ for (QDomElement publicPreKeyElement = publicPreKeysElement.firstChildElement(QStringLiteral("pk"));
+ !publicPreKeyElement.isNull();
+ publicPreKeyElement = publicPreKeyElement.nextSiblingElement(QStringLiteral("pk"))) {
+ d->publicPreKeys.insert(publicPreKeyElement.attribute(QStringLiteral("id")).toInt(), QByteArray::fromBase64(publicPreKeyElement.text().toLatin1()));
+ }
+ }
+}
+
+void QXmppOmemoDeviceBundle::toXml(QXmlStreamWriter *writer) const
+{
+ writer->writeStartElement(QStringLiteral("bundle"));
+ writer->writeDefaultNamespace(ns_omemo_1);
+
+ writer->writeStartElement(QStringLiteral("ik"));
+ writer->writeCharacters(publicIdentityKey().toBase64());
+ writer->writeEndElement();
+
+ writer->writeStartElement(QStringLiteral("spk"));
+ writer->writeAttribute(QStringLiteral("id"), QString::number(signedPublicPreKeyId()));
+ writer->writeCharacters(signedPublicPreKey().toBase64());
+ writer->writeEndElement();
+
+ writer->writeStartElement(QStringLiteral("spks"));
+ writer->writeCharacters(signedPublicPreKeySignature().toBase64());
+ writer->writeEndElement();
+
+ writer->writeStartElement(QStringLiteral("prekeys"));
+ for (auto it = d->publicPreKeys.cbegin(); it != d->publicPreKeys.cend(); it++) {
+ writer->writeStartElement(QStringLiteral("pk"));
+ writer->writeAttribute(QStringLiteral("id"), QString::number(it.key()));
+ writer->writeCharacters(it.value().toBase64());
+ writer->writeEndElement();
+ }
+ writer->writeEndElement(); // prekeys
+
+ writer->writeEndElement(); // bundle
+}
+/// \endcond
+
+///
+/// Determines whether the given DOM element is an OMEMO device bundle.
+///
+/// \param element DOM element being checked
+///
+/// \return true if element is an OMEMO device bundle, otherwise false
+///
+bool QXmppOmemoDeviceBundle::isOmemoDeviceBundle(const QDomElement &element)
+{
+ return element.tagName() == QStringLiteral("bundle") &&
+ element.namespaceURI() == ns_omemo_1;
+}