diff options
author | Carl Schwan <carl@carlschwan.eu> | 2021-01-30 00:21:10 +0100 |
---|---|---|
committer | Tobias Fella <fella@posteo.de> | 2021-12-01 21:34:52 +0100 |
commit | f9f7d130e5768d0f69edc8900d37f540b61fa974 (patch) | |
tree | 911e5cadf505519451940e8632144b30c8fac693 /lib/crypto | |
parent | 10b89faeea9e385ea901d45418491cd91dff99b9 (diff) | |
download | libquotient-f9f7d130e5768d0f69edc8900d37f540b61fa974.tar.gz libquotient-f9f7d130e5768d0f69edc8900d37f540b61fa974.zip |
Key verification
Diffstat (limited to 'lib/crypto')
-rw-r--r-- | lib/crypto/qolmaccount.cpp | 42 | ||||
-rw-r--r-- | lib/crypto/qolmaccount.h | 9 | ||||
-rw-r--r-- | lib/crypto/qolmutility.cpp | 58 | ||||
-rw-r--r-- | lib/crypto/qolmutility.h | 48 |
4 files changed, 157 insertions, 0 deletions
diff --git a/lib/crypto/qolmaccount.cpp b/lib/crypto/qolmaccount.cpp index fb91c906..24fd87f2 100644 --- a/lib/crypto/qolmaccount.cpp +++ b/lib/crypto/qolmaccount.cpp @@ -7,6 +7,7 @@ #include "connection.h" #include "csapi/keys.h" #include "crypto/qolmutils.h" +#include "crypto/qolmutility.h" #include <QJsonObject> #include <QJsonDocument> #include <QDebug> @@ -263,4 +264,45 @@ std::variant<std::unique_ptr<QOlmSession>, QOlmError> QOlmAccount::createOutboun return QOlmSession::createOutboundSession(this, theirIdentityKey, theirOneTimeKey); } +bool Quotient::verifyIdentitySignature(const DeviceKeys &deviceKeys, + const QString &deviceId, + const QString &userId) +{ + const auto signKeyId = "ed25519:" + deviceId; + const auto signingKey = deviceKeys.keys[signKeyId]; + const auto signature = deviceKeys.signatures[userId][signKeyId]; + + if (signature.isEmpty()) { + return false; + } + + return ed25519VerifySignature(signingKey, toJson(deviceKeys), signature); +} + +bool Quotient::ed25519VerifySignature(QString signingKey, + QJsonObject obj, + QString signature) +{ + if (signature.isEmpty()) { + return false; + } + + obj.remove("unsigned"); + obj.remove("signatures"); + + QJsonDocument doc; + doc.setObject(obj); + auto canonicalJson = doc.toJson(); + + QByteArray signingKeyBuf = signingKey.toUtf8(); + QOlmUtility utility; + auto signatureBuf = signature.toUtf8(); + auto result = utility.ed25519Verify(signingKeyBuf, canonicalJson, signatureBuf); + if (std::holds_alternative<QOlmError>(result)) { + return false; + } + + return std::get<bool>(result); +} + #endif diff --git a/lib/crypto/qolmaccount.h b/lib/crypto/qolmaccount.h index d61c8748..09ef623a 100644 --- a/lib/crypto/qolmaccount.h +++ b/lib/crypto/qolmaccount.h @@ -99,6 +99,15 @@ private: QString m_deviceId; }; +bool verifyIdentitySignature(const DeviceKeys &deviceKeys, + const QString &deviceId, + const QString &userId); + +//! checks if the signature is signed by the signing_key +bool ed25519VerifySignature(QString signingKey, + QJsonObject obj, + QString signature); + } // namespace Quotient #endif diff --git a/lib/crypto/qolmutility.cpp b/lib/crypto/qolmutility.cpp new file mode 100644 index 00000000..3c6a14c7 --- /dev/null +++ b/lib/crypto/qolmutility.cpp @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org> +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifdef Quotient_E2EE_ENABLED +#include "crypto/qolmutility.h" +#include "olm/olm.h" + +using namespace Quotient; + +// Convert olm error to enum +QOlmError lastError(OlmUtility *utility) { + const std::string error_raw = olm_utility_last_error(utility); + + return fromString(error_raw); +} + +QOlmUtility::QOlmUtility() +{ + auto utility = new uint8_t[olm_utility_size()]; + m_utility = olm_utility(utility); +} + +QOlmUtility::~QOlmUtility() +{ + olm_clear_utility(m_utility); + delete[](reinterpret_cast<uint8_t *>(m_utility)); +} + +QString QOlmUtility::sha256Bytes(const QByteArray &inputBuf) const +{ + const auto outputLen = olm_sha256_length(m_utility); + QByteArray outputBuf(outputLen, '0'); + olm_sha256(m_utility, inputBuf.data(), inputBuf.length(), + outputBuf.data(), outputBuf.length()); + + return QString::fromUtf8(outputBuf); +} + +QString QOlmUtility::sha256Utf8Msg(const QString &message) const +{ + return sha256Bytes(message.toUtf8()); +} + +std::variant<bool, QOlmError> QOlmUtility::ed25519Verify(const QByteArray &key, + const QByteArray &message, QByteArray &signature) +{ + const auto error = olm_ed25519_verify(m_utility, key.data(), key.length(), + message.data(), message.length(), signature.data(), signature.length()); + + if (error == olm_error()) { + return lastError(m_utility); + } + return error == 0; +} + + +#endif diff --git a/lib/crypto/qolmutility.h b/lib/crypto/qolmutility.h new file mode 100644 index 00000000..16c330eb --- /dev/null +++ b/lib/crypto/qolmutility.h @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org> +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#pragma once + +#ifdef Quotient_E2EE_ENABLED +#include <QObject> +#include <variant> +#include "crypto/qolmerrors.h" + +struct OlmUtility; + +namespace Quotient { + +class QOlmSession; +class Connection; + +//! Allows you to make use of crytographic hashing via SHA-2 and +//! verifying ed25519 signatures. +class QOlmUtility +{ +public: + QOlmUtility(); + ~QOlmUtility(); + + //! Returns a sha256 of the supplied byte slice. + QString sha256Bytes(const QByteArray &inputBuf) const; + + //! Convenience function that converts the UTF-8 message + //! to bytes and then calls `sha256_bytes()`, returning its output. + QString sha256Utf8Msg(const QString &message) const; + + //! Verify a ed25519 signature. + //! \param any QByteArray The public part of the ed25519 key that signed the message. + //! \param message QByteArray The message that was signed. + //! \param signature QByteArray The signature of the message. + std::variant<bool, QOlmError> ed25519Verify(const QByteArray &key, + const QByteArray &message, QByteArray &signature); + + +private: + OlmUtility *m_utility; + +}; +} + +#endif |