aboutsummaryrefslogtreecommitdiff
path: root/src/base
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
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')
-rw-r--r--src/base/QXmppOmemoData.cpp234
-rw-r--r--src/base/QXmppOmemoDeviceBundle.h73
2 files changed, 307 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;
+}
diff --git a/src/base/QXmppOmemoDeviceBundle.h b/src/base/QXmppOmemoDeviceBundle.h
new file mode 100644
index 00000000..b687c78b
--- /dev/null
+++ b/src/base/QXmppOmemoDeviceBundle.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008-2021 The QXmpp developers
+ *
+ * Author:
+ * Germán Márquez Mejía
+ * Melvin Keskin
+ *
+ * Source:
+ * https://github.com/qxmpp-project/qxmpp
+ *
+ * This file is a part of QXmpp library.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#ifndef QXMPPOMEMODEVICEBUNDLE_H
+#define QXMPPOMEMODEVICEBUNDLE_H
+
+#include "QXmppGlobal.h"
+
+#include <QSharedDataPointer>
+
+class QDomElement;
+class QXmppOmemoDeviceBundlePrivate;
+class QXmlStreamWriter;
+
+class QXMPP_EXPORT QXmppOmemoDeviceBundle
+{
+public:
+ QXmppOmemoDeviceBundle();
+ QXmppOmemoDeviceBundle(const QXmppOmemoDeviceBundle &other);
+ ~QXmppOmemoDeviceBundle();
+
+ QXmppOmemoDeviceBundle &operator=(const QXmppOmemoDeviceBundle &other);
+
+ QByteArray publicIdentityKey() const;
+ void setPublicIdentityKey(const QByteArray &key);
+
+ QByteArray signedPublicPreKey() const;
+ void setSignedPublicPreKey(const QByteArray &key);
+
+ uint32_t signedPublicPreKeyId() const;
+ void setSignedPublicPreKeyId(uint32_t id);
+
+ QByteArray signedPublicPreKeySignature() const;
+ void setSignedPublicPreKeySignature(const QByteArray &signature);
+
+ QMap<uint32_t, QByteArray> publicPreKeys() const;
+ void setPublicPreKeys(const QMap<uint32_t, QByteArray> &keys);
+
+ /// \cond
+ void parse(const QDomElement &element);
+ void toXml(QXmlStreamWriter *writer) const;
+ /// \endcond
+
+ static bool isOmemoDeviceBundle(const QDomElement &element);
+
+private:
+ QSharedDataPointer<QXmppOmemoDeviceBundlePrivate> d;
+};
+
+Q_DECLARE_TYPEINFO(QXmppOmemoDeviceBundle, Q_MOVABLE_TYPE);
+
+#endif // QXMPPOMEMODEVICEBUNDLE_H