diff options
Diffstat (limited to 'lib/e2ee/e2ee.h')
-rw-r--r-- | lib/e2ee/e2ee.h | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/lib/e2ee/e2ee.h b/lib/e2ee/e2ee.h index 268cb525..0772b70a 100644 --- a/lib/e2ee/e2ee.h +++ b/lib/e2ee/e2ee.h @@ -6,9 +6,13 @@ #pragma once #include "converters.h" -#include "quotient_common.h" +#include "expected.h" +#include "qolmerrors.h" #include <QtCore/QMetaType> +#include <QtCore/QStringBuilder> + +#include <array> #include <variant> namespace Quotient { @@ -33,10 +37,11 @@ constexpr auto SignedCurve25519Key = "signed_curve25519"_ls; constexpr auto OlmV1Curve25519AesSha2AlgoKey = "m.olm.v1.curve25519-aes-sha2"_ls; constexpr auto MegolmV1AesSha2AlgoKey = "m.megolm.v1.aes-sha2"_ls; +constexpr std::array SupportedAlgorithms { OlmV1Curve25519AesSha2AlgoKey, + MegolmV1AesSha2AlgoKey }; + inline bool isSupportedAlgorithm(const QString& algorithm) { - static constexpr auto SupportedAlgorithms = - make_array(OlmV1Curve25519AesSha2AlgoKey, MegolmV1AesSha2AlgoKey); return std::find(SupportedAlgorithms.cbegin(), SupportedAlgorithms.cend(), algorithm) != SupportedAlgorithms.cend(); @@ -55,6 +60,12 @@ using QOlmSessionPtr = std::unique_ptr<QOlmSession>; class QOlmInboundGroupSession; using QOlmInboundGroupSessionPtr = std::unique_ptr<QOlmInboundGroupSession>; +class QOlmOutboundGroupSession; +using QOlmOutboundGroupSessionPtr = std::unique_ptr<QOlmOutboundGroupSession>; + +template <typename T> +using QOlmExpected = Expected<T, QOlmError>; + struct IdentityKeys { QByteArray curve25519; @@ -62,45 +73,66 @@ struct IdentityKeys }; //! Struct representing the one-time keys. -struct QUOTIENT_API OneTimeKeys +struct UnsignedOneTimeKeys { QHash<QString, QHash<QString, QString>> keys; //! Get the HashMap containing the curve25519 one-time keys. - QHash<QString, QString> curve25519() const; - - //! Get a reference to the hashmap corresponding to given key type. -// std::optional<QHash<QString, QString>> get(QString keyType) const; + QHash<QString, QString> curve25519() const { return keys[Curve25519Key]; } }; -//! Struct representing the signed one-time keys. -class SignedOneTimeKey -{ +class SignedOneTimeKey { public: - //! Required. The unpadded Base64-encoded 32-byte Curve25519 public key. - QString key; + explicit SignedOneTimeKey(const QString& unsignedKey, const QString& userId, + const QString& deviceId, + const QByteArray& signature) + : payload { { "key"_ls, unsignedKey }, + { "signatures"_ls, + QJsonObject { + { userId, QJsonObject { { "ed25519:"_ls % deviceId, + QString(signature) } } } } } } + {} + explicit SignedOneTimeKey(const QJsonObject& jo = {}) + : payload(jo) + {} - //! Required. Signatures of the key object. - //! The signature is calculated using the process described at Signing JSON. - QHash<QString, QHash<QString, QString>> signatures; -}; + //! Unpadded Base64-encoded 32-byte Curve25519 public key + QString key() const { return payload["key"_ls].toString(); } + //! \brief Signatures of the key object + //! + //! The signature is calculated using the process described at + //! https://spec.matrix.org/v1.3/appendices/#signing-json + auto signatures() const + { + return fromJson<QHash<QString, QHash<QString, QString>>>( + payload["signatures"_ls]); + } -template <> -struct JsonObjectConverter<SignedOneTimeKey> { - static void fillFrom(const QJsonObject& jo, SignedOneTimeKey& result) + QByteArray signature(QStringView userId, QStringView deviceId) const { - fromJson(jo.value("key"_ls), result.key); - fromJson(jo.value("signatures"_ls), result.signatures); + return payload["signatures"_ls][userId]["ed25519:"_ls % deviceId] + .toString() + .toLatin1(); } - static void dumpTo(QJsonObject &jo, const SignedOneTimeKey &result) + //! Whether the key is a fallback key + bool isFallback() const { return payload["fallback"_ls].toBool(); } + auto toJson() const { return payload; } + auto toJsonForVerification() const { - addParam<>(jo, QStringLiteral("key"), result.key); - addParam<>(jo, QStringLiteral("signatures"), result.signatures); + auto json = payload; + json.remove("signatures"_ls); + json.remove("unsigned"_ls); + return QJsonDocument(json).toJson(QJsonDocument::Compact); } + +private: + QJsonObject payload; }; +using OneTimeKeys = QHash<QString, std::variant<QString, SignedOneTimeKey>>; + template <typename T> class asKeyValueRange { |