diff options
| author | Melvin Keskin <melvo@olomono.de> | 2021-09-02 23:35:11 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2021-09-03 16:16:14 +0200 |
| commit | 11db6293ced5c4665630ad3d728aba5751a3f658 (patch) | |
| tree | 93e8536de8daa881d8ee84b28b7bc5e0a3571572 /src/base/QXmppOmemoData.cpp | |
| parent | 2ccc8d2d7033bb7180638ec8f980b904cfe3d686 (diff) | |
| download | qxmpp-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.cpp | 234 |
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; +} |
