Skip to content
Snippets Groups Projects
Commit 147836c8 authored by Konstantinos Sideris's avatar Konstantinos Sideris
Browse files

Refactor OlmClient to only use the C API

parent ef67bdbc
No related branches found
No related tags found
No related merge requests found
......@@ -6,163 +6,205 @@
using json = nlohmann::json;
using namespace mtx::client::crypto;
constexpr std::size_t SIGNATURE_SIZE = 64;
std::shared_ptr<olm::Account>
mtx::client::crypto::olm_new_account()
void
OlmClient::create_new_account()
{
auto olm_account = std::make_shared<olm::Account>();
// The method has no effect if the account is already initialized.
if (account_)
return;
const auto nbytes = olm_account->new_account_random_length();
auto buf = create_buffer(nbytes);
account_ =
std::unique_ptr<OlmAccount, OlmDeleter>(olm_account(new uint8_t[olm_account_size()]));
int result = olm_account->new_account(buf->data(), buf->size());
auto tmp_buf = create_buffer(olm_create_account_random_length(account_.get()));
const int ret = olm_create_account(account_.get(), tmp_buf->data(), tmp_buf->size());
if (result == -1)
throw olm_exception("olm_new_account", olm_account->last_error);
if (ret == -1) {
account_.reset();
throw olm_exception("create_new_account", account_.get());
}
}
return olm_account;
void
OlmClient::create_new_utility()
{
// The method has no effect if the account is already initialized.
if (utility_)
return;
utility_ =
std::unique_ptr<OlmUtility, OlmDeleter>(olm_utility(new uint8_t[olm_utility_size()]));
}
IdentityKeys
mtx::client::crypto::identity_keys(std::shared_ptr<olm::Account> account)
std::unique_ptr<OlmSession, OlmDeleter>
OlmClient::create_new_session()
{
const auto nbytes = account->get_identity_json_length();
auto buf = create_buffer(nbytes);
return std::unique_ptr<OlmSession, OlmDeleter>(
olm_session(new uint8_t[olm_session_size()]));
}
int result = account->get_identity_json(buf->data(), buf->size());
IdentityKeys
OlmClient::identity_keys()
{
auto tmp_buf = create_buffer(olm_account_identity_keys_length(account_.get()));
int result =
olm_account_identity_keys(account_.get(), (void *)tmp_buf->data(), tmp_buf->size());
if (result == -1)
throw olm_exception("identity_keys", account->last_error);
throw olm_exception("identity_keys", account_.get());
return json::parse(std::string(tmp_buf->begin(), tmp_buf->end()));
}
std::unique_ptr<BinaryBuf>
OlmClient::sign_message(const std::string &msg)
{
// Message buffer
auto buf = str_to_buffer(msg);
std::string data(buf->begin(), buf->end());
IdentityKeys keys = json::parse(data);
// Signature buffer
auto signature_buf = create_buffer(olm_account_signature_length(account_.get()));
olm_account_sign(
account_.get(), buf->data(), buf->size(), signature_buf->data(), signature_buf->size());
return keys;
return signature_buf;
}
std::string
mtx::client::crypto::sign_identity_keys(std::shared_ptr<olm::Account> account,
const IdentityKeys &keys,
const mtx::identifiers::User &user_id,
const std::string &device_id)
OlmClient::sign_identity_keys()
{
auto keys = identity_keys();
json body{{"algorithms", {"m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"}},
{"user_id", user_id.to_string()},
{"device_id", device_id},
{"user_id", user_id_},
{"device_id", device_id_},
{"keys",
{
{"curve25519:" + device_id, keys.curve25519},
{"ed25519:" + device_id, keys.ed25519},
{"curve25519:" + device_id_, keys.curve25519},
{"ed25519:" + device_id_, keys.ed25519},
}}};
return encode_base64(sign_message(account, body.dump())->data(), SIGNATURE_SIZE);
return encode_base64(sign_message(body.dump())->data(),
olm_account_signature_length(account_.get()));
}
std::size_t
mtx::client::crypto::generate_one_time_keys(std::shared_ptr<olm::Account> account,
std::size_t number_of_keys)
OlmClient::generate_one_time_keys(std::size_t number_of_keys)
{
const auto nbytes = account->generate_one_time_keys_random_length(number_of_keys);
const std::size_t nbytes =
olm_account_generate_one_time_keys_random_length(account_.get(), number_of_keys);
auto buf = create_buffer(nbytes);
return account->generate_one_time_keys(number_of_keys, buf->data(), buf->size());
const int ret = olm_account_generate_one_time_keys(
account_.get(), number_of_keys, buf->data(), buf->size());
if (ret == -1)
throw olm_exception("generate_one_time_keys", account_.get());
return ret;
}
json
mtx::client::crypto::one_time_keys(std::shared_ptr<olm::Account> account)
OneTimeKeys
OlmClient::one_time_keys()
{
const auto nbytes = account->get_one_time_keys_json_length();
auto buf = create_buffer(nbytes);
auto buf = create_buffer(olm_account_one_time_keys_length(account_.get()));
int result = account->get_one_time_keys_json(buf->data(), buf->size());
const int ret = olm_account_one_time_keys(account_.get(), buf->data(), buf->size());
if (result == -1)
throw olm_exception("one_time_keys", account->last_error);
if (ret == -1)
throw olm_exception("one_time_keys", account_.get());
return json::parse(std::string(buf->begin(), buf->end()));
}
std::string
mtx::client::crypto::sign_one_time_key(std::shared_ptr<olm::Account> account,
const std::string &key)
OlmClient::sign_one_time_key(const std::string &key)
{
json j{{"key", key}};
auto str_json = j.dump();
auto str_json = j.dump();
auto signature = sign_message(j.dump());
auto signature_buf = sign_message(account, j.dump());
return encode_base64(signature_buf->data(), signature_buf->size());
return encode_base64(signature->data(), signature->size());
}
std::map<std::string, json>
mtx::client::crypto::sign_one_time_keys(std::shared_ptr<olm::Account> account,
const mtx::client::crypto::OneTimeKeys &keys,
const mtx::identifiers::User &user_id,
const std::string &device_id)
OlmClient::sign_one_time_keys(const OneTimeKeys &keys)
{
// Sign & append the one time keys.
std::map<std::string, json> signed_one_time_keys;
for (const auto &elem : keys.curve25519) {
auto sig = sign_one_time_key(account, elem.second);
auto sig = sign_one_time_key(elem.second);
signed_one_time_keys["signed_curve25519:" + elem.first] =
signed_one_time_key_json(user_id, device_id, elem.second, sig);
signed_one_time_key_json(elem.second, sig);
}
return signed_one_time_keys;
}
json
OlmClient::signed_one_time_key_json(const std::string &key, const std::string &signature)
{
return json{{"key", key},
{"signatures", {{user_id_, {{"ed25519:" + device_id_, signature}}}}}};
}
mtx::requests::UploadKeys
OlmClient::create_upload_keys_request()
{
return create_upload_keys_request(one_time_keys());
}
mtx::requests::UploadKeys
mtx::client::crypto::create_upload_keys_request(
std::shared_ptr<olm::Account> account,
const mtx::client::crypto::IdentityKeys &identity_keys,
const mtx::client::crypto::OneTimeKeys &one_time_keys,
const mtx::identifiers::User &user_id,
const std::string &device_id)
OlmClient::create_upload_keys_request(const mtx::client::crypto::OneTimeKeys &one_time_keys)
{
mtx::requests::UploadKeys req;
req.device_keys.user_id = user_id.to_string();
req.device_keys.device_id = device_id;
req.device_keys.user_id = user_id_;
req.device_keys.device_id = device_id_;
auto id_keys = identity_keys();
req.device_keys.keys["curve25519:" + device_id] = identity_keys.curve25519;
req.device_keys.keys["ed25519:" + device_id] = identity_keys.ed25519;
req.device_keys.keys["curve25519:" + device_id_] = id_keys.curve25519;
req.device_keys.keys["ed25519:" + device_id_] = id_keys.ed25519;
// Generate and add the signature to the request.
auto sig = sign_identity_keys(account, identity_keys, user_id, device_id);
req.device_keys.signatures[user_id.to_string()]["ed25519:" + device_id] = sig;
auto sig = sign_identity_keys();
req.device_keys.signatures[user_id_]["ed25519:" + device_id_] = sig;
if (one_time_keys.curve25519.empty())
return req;
// Sign & append the one time keys.
req.one_time_keys =
mtx::client::crypto::sign_one_time_keys(account, one_time_keys, user_id, device_id);
req.one_time_keys = sign_one_time_keys(one_time_keys);
return req;
}
std::unique_ptr<BinaryBuf>
mtx::client::crypto::sign_message(std::shared_ptr<olm::Account> account, const std::string &msg)
std::unique_ptr<OlmSession, OlmDeleter>
OlmClient::create_outbound_group_session(const std::string &peer_identity_key,
const std::string &peer_one_time_key)
{
// Message buffer
auto buf = str_to_buffer(msg);
auto session = create_new_session();
auto tmp_buf = create_buffer(olm_create_outbound_session_random_length(session.get()));
// Signature buffer
auto signature_buf = create_buffer(SIGNATURE_SIZE);
account->sign(buf->data(), buf->size(), signature_buf->data(), signature_buf->size());
auto idk_buf = str_to_buffer(peer_identity_key);
auto otk_buf = str_to_buffer(peer_one_time_key);
return signature_buf;
}
const int ret = olm_create_outbound_session(session.get(),
account_.get(),
idk_buf->data(),
idk_buf->size(),
otk_buf->data(),
otk_buf->size(),
tmp_buf->data(),
tmp_buf->size());
json
mtx::client::crypto::signed_one_time_key_json(const mtx::identifiers::User &user_id,
const std::string &device_id,
const std::string &key,
const std::string &signature)
{
return json{{"key", key},
{"signatures", {{user_id.to_string(), {{"ed25519:" + device_id, signature}}}}}};
if (ret == -1)
throw olm_exception("init_outbound_group_session", session.get());
return session;
}
std::unique_ptr<BinaryBuf>
......@@ -213,34 +255,3 @@ mtx::client::crypto::json_to_buffer(const nlohmann::json &obj)
{
return str_to_buffer(obj.dump());
}
_olm_curve25519_public_key
mtx::client::crypto::str_to_curve25519_pk(const std::string &data)
{
auto decoded = decode_base64(data);
if (decoded->size() != CURVE25519_KEY_LENGTH)
throw olm_exception("str_to_curve25519_pk: invalid input size");
_olm_curve25519_public_key pk;
std::copy(decoded->begin(), decoded->end(), pk.public_key);
return pk;
}
olm::Session
mtx::client::crypto::init_outbound_group_session(std::shared_ptr<olm::Account> account,
const std::string &peer_identity_key,
const std::string &peer_one_time_key)
{
olm::Session session;
auto buf = create_buffer(session.new_outbound_session_random_length());
session.new_outbound_session(*account,
str_to_curve25519_pk(peer_identity_key),
str_to_curve25519_pk(peer_one_time_key),
buf->data(),
buf->size());
return session;
}
......@@ -2,6 +2,7 @@
#include <exception>
#include <memory>
#include <new>
#include <json.hpp>
#include <sodium.h>
......@@ -13,6 +14,8 @@
#include <olm/error.h>
#include <olm/session.hh>
#include <olm/olm.h>
namespace mtx {
namespace client {
namespace crypto {
......@@ -66,41 +69,28 @@ from_json(const nlohmann::json &obj, OneTimeKeys &keys)
class olm_exception : public std::exception
{
public:
olm_exception(std::string msg, OlmErrorCode errcode)
: errcode_(errcode)
, msg_(msg + ": " + std::string(_olm_error_to_string(errcode)))
olm_exception(std::string func, OlmSession *s)
: msg_(func + ": " + std::string(olm_session_last_error(s)))
{}
olm_exception(std::string func, OlmAccount *acc)
: msg_(func + ": " + std::string(olm_account_last_error(acc)))
{}
olm_exception(std::string func, OlmUtility *util)
: msg_(func + ": " + std::string(olm_utility_last_error(util)))
{}
olm_exception(std::string msg)
: msg_(msg)
{}
OlmErrorCode get_errcode() const { return errcode_; }
const char *get_error() const { return _olm_error_to_string(errcode_); }
virtual const char *what() const throw() { return msg_.c_str(); }
private:
OlmErrorCode errcode_;
std::string msg_;
};
//! Create a new olm Account.
std::shared_ptr<olm::Account>
olm_new_account();
//! Retrieve the json representation of the identity keys for the given account.
IdentityKeys
identity_keys(std::shared_ptr<olm::Account> user);
//! Generate a number of one time keys.
std::size_t
generate_one_time_keys(std::shared_ptr<olm::Account> account, std::size_t number_of_keys);
//! Retrieve the json representation of the one time keys for the given account.
nlohmann::json
one_time_keys(std::shared_ptr<olm::Account> user);
//! Create a uint8_t buffer which is initialized with random bytes.
template<class T = BinaryBuf>
std::unique_ptr<T>
......@@ -112,42 +102,72 @@ create_buffer(std::size_t nbytes)
return buf;
}
//! Sign the given one time keys and encode it to base64.
std::string
sign_one_time_key(std::shared_ptr<olm::Account> account, const std::string &key);
struct OlmDeleter
{
void operator()(OlmAccount *ptr) { operator delete(ptr, olm_account_size()); }
void operator()(OlmSession *ptr) { operator delete(ptr, olm_session_size()); }
void operator()(OlmUtility *ptr) { operator delete(ptr, olm_utility_size()); }
};
//! Sign the identity keys. The result should be used as part of the /keys/upload/ request.
std::string
sign_identity_keys(std::shared_ptr<olm::Account> account,
const IdentityKeys &keys,
const mtx::identifiers::User &user_id,
const std::string &device_id);
class OlmClient : public std::enable_shared_from_this<OlmClient>
{
public:
OlmClient() = default;
OlmClient(std::string user_id, std::string device_id)
: user_id_(std::move(user_id))
, device_id_(std::move(device_id))
{}
//! Sign the given message.
std::unique_ptr<BinaryBuf>
sign_message(std::shared_ptr<olm::Account> account, const std::string &msg);
//! Generate the json structure for the signed one time key.
nlohmann::json
signed_one_time_key_json(const mtx::identifiers::User &user_id,
const std::string &device_id,
const std::string &key,
const std::string &signature);
//! Sign one_time_keys and generate the appropriate structure for the /keys/upload request.
std::map<std::string, nlohmann::json>
sign_one_time_keys(std::shared_ptr<olm::Account> account,
const mtx::client::crypto::OneTimeKeys &keys,
const mtx::identifiers::User &user_id,
const std::string &device_id);
//! Prepare request for the /keys/upload endpoint by signing identity & one time keys.
mtx::requests::UploadKeys
create_upload_keys_request(std::shared_ptr<olm::Account> account,
const mtx::client::crypto::IdentityKeys &identity_keys,
const mtx::client::crypto::OneTimeKeys &one_time_keys,
const mtx::identifiers::User &user_id,
const std::string &device_id);
using Base64String = std::string;
using SignedOneTimeKeys = std::map<std::string, json>;
void set_device_id(std::string device_id) { device_id_ = std::move(device_id); }
void set_user_id(std::string user_id) { user_id_ = std::move(user_id); }
//! Sign the given message.
std::unique_ptr<BinaryBuf> sign_message(const std::string &msg);
//! Create a new olm Account. Must be called before any other operation.
void create_new_account();
void create_new_utility();
std::unique_ptr<OlmSession, OlmDeleter> create_new_session();
//! Retrieve the json representation of the identity keys for the given account.
IdentityKeys identity_keys();
//! Sign the identity keys.
//! The result should be used as part of the /keys/upload/ request.
Base64String sign_identity_keys();
//! Generate a number of one time keys.
std::size_t generate_one_time_keys(std::size_t nkeys);
//! Retrieve the json representation of the one time keys for the given account.
OneTimeKeys one_time_keys();
//! Sign the given one time keys and encode it to base64.
Base64String sign_one_time_key(const Base64String &encoded_key);
//! Sign one_time_keys and generate the appropriate structure for the /keys/upload request.
SignedOneTimeKeys sign_one_time_keys(const OneTimeKeys &keys);
//! Generate the json structure for the signed one time key.
json signed_one_time_key_json(const std::string &key, const std::string &signature);
//! Prepare request for the /keys/upload endpoint by signing identity & one time keys.
mtx::requests::UploadKeys create_upload_keys_request(const OneTimeKeys &keys);
mtx::requests::UploadKeys create_upload_keys_request();
//! Create an outbount megolm session.
std::unique_ptr<OlmSession, OlmDeleter> create_outbound_group_session(
const std::string &peer_identity_key,
const std::string &peer_one_time_key);
OlmAccount *account() { return account_.get(); }
OlmUtility *utility() { return utility_.get(); }
private:
std::string user_id_;
std::string device_id_;
std::unique_ptr<OlmAccount, OlmDeleter> account_;
std::unique_ptr<OlmUtility, OlmDeleter> utility_;
};
std::string
encode_base64(const uint8_t *data, std::size_t len);
......@@ -156,23 +176,13 @@ encode_base64(const uint8_t *data, std::size_t len);
std::unique_ptr<BinaryBuf>
decode_base64(const std::string &data);
//! Convert the given string to an uint8_t buffer.
std::unique_ptr<BinaryBuf>
str_to_buffer(const std::string &data);
//! Convert the given json struct to an uint8_t buffer.
std::unique_ptr<BinaryBuf>
json_to_buffer(const nlohmann::json &obj);
//! Convert from base64 encoded public key.
_olm_curve25519_public_key
str_to_curve25519_pk(const std::string &data);
//! Create an outbount megolm session.
olm::Session
init_outbound_group_session(std::shared_ptr<olm::Account> account,
const std::string &peer_id_key,
const std::string &peer_one_time_key);
//! Convert the given string to an uint8_t buffer.
std::unique_ptr<BinaryBuf>
str_to_buffer(const std::string &data);
} // namespace crypto
} // namespace client
......
......@@ -23,23 +23,20 @@ using namespace mtx::responses;
using namespace std;
mtx::requests::UploadKeys
generate_keys(std::shared_ptr<olm::Account> account,
const mtx::identifiers::User &user_id,
const std::string &device_id)
generate_keys(std::shared_ptr<mtx::client::crypto::OlmClient> account)
{
auto idks = mtx::client::crypto::identity_keys(account);
auto idks = account->identity_keys();
account->generate_one_time_keys(1);
auto otks = account->one_time_keys();
mtx::client::crypto::generate_one_time_keys(account, 1);
auto otks = mtx::client::crypto::one_time_keys(account);
return mtx::client::crypto::create_upload_keys_request(
account, idks, otks, user_id, device_id);
return account->create_upload_keys_request(otks);
}
TEST(Encryption, UploadIdentityKeys)
{
auto alice = std::make_shared<Client>("localhost");
auto olm_account = mtx::client::crypto::olm_new_account();
auto olm_account = std::make_shared<mtx::client::crypto::OlmClient>();
olm_account->create_new_account();
alice->login("alice", "secret", [](const mtx::responses::Login &, RequestErr err) {
check_error(err);
......@@ -48,14 +45,16 @@ TEST(Encryption, UploadIdentityKeys)
while (alice->access_token().empty())
sleep();
auto identity_keys = mtx::client::crypto::identity_keys(olm_account);
olm_account->set_user_id(alice->user_id().to_string());
olm_account->set_device_id(alice->device_id());
auto id_keys = olm_account->identity_keys();
ASSERT_TRUE(identity_keys.curve25519.size() > 10);
ASSERT_TRUE(identity_keys.curve25519.size() > 10);
ASSERT_TRUE(id_keys.curve25519.size() > 10);
ASSERT_TRUE(id_keys.curve25519.size() > 10);
mtx::client::crypto::OneTimeKeys unused;
auto request = mtx::client::crypto::create_upload_keys_request(
olm_account, identity_keys, unused, alice->user_id(), alice->device_id());
auto request = olm_account->create_upload_keys_request(unused);
// Make the request with the signed identity keys.
alice->upload_keys(request, [](const mtx::responses::UploadKeys &res, RequestErr err) {
......@@ -69,7 +68,8 @@ TEST(Encryption, UploadIdentityKeys)
TEST(Encryption, UploadOneTimeKeys)
{
auto alice = std::make_shared<Client>("localhost");
auto olm_account = mtx::client::crypto::olm_new_account();
auto olm_account = std::make_shared<mtx::client::crypto::OlmClient>();
olm_account->create_new_account();
alice->login("alice", "secret", [](const mtx::responses::Login &, RequestErr err) {
check_error(err);
......@@ -78,17 +78,20 @@ TEST(Encryption, UploadOneTimeKeys)
while (alice->access_token().empty())
sleep();
auto nkeys = mtx::client::crypto::generate_one_time_keys(olm_account, 5);
olm_account->set_user_id(alice->user_id().to_string());
olm_account->set_device_id(alice->device_id());
auto nkeys = olm_account->generate_one_time_keys(5);
EXPECT_EQ(nkeys, 5);
auto one_time_keys = mtx::client::crypto::one_time_keys(olm_account);
json otks = olm_account->one_time_keys();
mtx::requests::UploadKeys req;
// Create the proper structure for uploading.
std::map<std::string, json> unsigned_keys;
auto obj = one_time_keys.at("curve25519");
auto obj = otks.at("curve25519");
for (auto it = obj.begin(); it != obj.end(); ++it)
unsigned_keys["curve25519:" + it.key()] = it.value();
......@@ -106,7 +109,8 @@ TEST(Encryption, UploadOneTimeKeys)
TEST(Encryption, UploadSignedOneTimeKeys)
{
auto alice = std::make_shared<Client>("localhost");
auto olm_account = mtx::client::crypto::olm_new_account();
auto olm_account = std::make_shared<mtx::client::crypto::OlmClient>();
olm_account->create_new_account();
alice->login("alice", "secret", [](const mtx::responses::Login &, RequestErr err) {
check_error(err);
......@@ -115,14 +119,16 @@ TEST(Encryption, UploadSignedOneTimeKeys)
while (alice->access_token().empty())
sleep();
auto nkeys = mtx::client::crypto::generate_one_time_keys(olm_account, 5);
olm_account->set_user_id(alice->user_id().to_string());
olm_account->set_device_id(alice->device_id());
auto nkeys = olm_account->generate_one_time_keys(5);
EXPECT_EQ(nkeys, 5);
auto one_time_keys = mtx::client::crypto::one_time_keys(olm_account);
auto one_time_keys = olm_account->one_time_keys();
mtx::requests::UploadKeys req;
req.one_time_keys = mtx::client::crypto::sign_one_time_keys(
olm_account, one_time_keys, alice->user_id(), alice->device_id());
req.one_time_keys = olm_account->sign_one_time_keys(one_time_keys);
alice->upload_keys(req, [nkeys](const mtx::responses::UploadKeys &res, RequestErr err) {
check_error(err);
......@@ -136,7 +142,8 @@ TEST(Encryption, UploadSignedOneTimeKeys)
TEST(Encryption, UploadKeys)
{
auto alice = std::make_shared<Client>("localhost");
auto olm_account = mtx::client::crypto::olm_new_account();
auto olm_account = std::make_shared<mtx::client::crypto::OlmClient>();
olm_account->create_new_account();
alice->login("alice", "secret", [](const mtx::responses::Login &, RequestErr err) {
check_error(err);
......@@ -145,7 +152,10 @@ TEST(Encryption, UploadKeys)
while (alice->access_token().empty())
sleep();
auto req = ::generate_keys(olm_account, alice->user_id(), alice->device_id());
olm_account->set_user_id(alice->user_id().to_string());
olm_account->set_device_id(alice->device_id());
auto req = generate_keys(olm_account);
alice->upload_keys(req, [](const mtx::responses::UploadKeys &res, RequestErr err) {
check_error(err);
......@@ -159,10 +169,13 @@ TEST(Encryption, UploadKeys)
TEST(Encryption, QueryKeys)
{
auto alice = std::make_shared<Client>("localhost");
auto alice_olm = mtx::client::crypto::olm_new_account();
auto alice_olm = std::make_shared<mtx::client::crypto::OlmClient>();
auto bob = std::make_shared<Client>("localhost");
auto bob_olm = mtx::client::crypto::olm_new_account();
auto bob_olm = std::make_shared<mtx::client::crypto::OlmClient>();
alice_olm->create_new_account();
bob_olm->create_new_account();
alice->login("alice", "secret", [](const mtx::responses::Login &, RequestErr err) {
check_error(err);
......@@ -174,9 +187,15 @@ TEST(Encryption, QueryKeys)
while (alice->access_token().empty() || bob->access_token().empty())
sleep();
alice_olm->set_user_id(alice->user_id().to_string());
alice_olm->set_device_id(alice->device_id());
bob_olm->set_user_id(bob->user_id().to_string());
bob_olm->set_device_id(bob->device_id());
// Create and upload keys for both users.
auto alice_req = ::generate_keys(alice_olm, alice->user_id(), alice->device_id());
auto bob_req = ::generate_keys(bob_olm, bob->user_id(), bob->device_id());
auto alice_req = ::generate_keys(alice_olm);
auto bob_req = ::generate_keys(bob_olm);
// Validates that both upload requests are finished.
atomic_int uploads(0);
......@@ -257,7 +276,8 @@ TEST(Encryption, QueryKeys)
TEST(Encryption, KeyChanges)
{
auto carl = std::make_shared<Client>("localhost");
auto carl_olm = mtx::client::crypto::olm_new_account();
auto carl_olm = std::make_shared<mtx::client::crypto::OlmClient>();
carl_olm->create_new_account();
carl->login("carl", "secret", [](const mtx::responses::Login &, RequestErr err) {
check_error(err);
......@@ -266,6 +286,9 @@ TEST(Encryption, KeyChanges)
while (carl->access_token().empty())
sleep();
carl_olm->set_device_id(carl->device_id());
carl_olm->set_user_id(carl->user_id().to_string());
mtx::requests::CreateRoom req;
carl->create_room(
req, [carl, carl_olm](const mtx::responses::CreateRoom &, RequestErr err) {
......@@ -281,8 +304,7 @@ TEST(Encryption, KeyChanges)
check_error(err);
const auto next_batch_token = res.next_batch;
auto key_req =
::generate_keys(carl_olm, carl->user_id(), carl->device_id());
auto key_req = ::generate_keys(carl_olm);
atomic_bool keys_uploaded(false);
......
......@@ -11,8 +11,6 @@ using json = nlohmann::json;
using namespace mtx::client::crypto;
using namespace std;
constexpr int SIGNATURE_SIZE = 64;
TEST(Utilities, JsonToBuffer)
{
auto msg = json({{"key", "text"}});
......@@ -23,33 +21,39 @@ TEST(Utilities, JsonToBuffer)
TEST(Utilities, VerifySignedOneTimeKey)
{
auto alice = olm_new_account();
auto alice = make_shared<OlmClient>();
alice->create_new_account();
alice->create_new_utility();
generate_one_time_keys(alice, 1);
auto keys = one_time_keys(alice);
alice->identity_keys();
auto first_key = keys["curve25519"].begin()->get<std::string>();
auto msg = json({{"key", first_key}}).dump();
alice->generate_one_time_keys(1);
auto keys = alice->one_time_keys();
auto sig_buf = sign_message(alice, msg);
auto first_key = keys.curve25519.begin()->second;
auto msg = json({{"key", first_key}}).dump();
olm::Utility utillity;
auto sig_buf = alice->sign_message(msg);
auto res = utillity.ed25519_verify(alice->identity_keys.ed25519_key.public_key,
str_to_buffer(msg)->data(),
msg.size(),
sig_buf->data(),
SIGNATURE_SIZE);
auto res = olm_ed25519_verify(alice->utility(),
str_to_buffer(alice->identity_keys().ed25519)->data(),
str_to_buffer(alice->identity_keys().ed25519)->size(),
str_to_buffer(msg)->data(),
str_to_buffer(msg)->size(),
sig_buf->data(),
sig_buf->size());
EXPECT_EQ(utillity.last_error, 0);
EXPECT_EQ(std::string(olm_utility_last_error(alice->utility())), "SUCCESS");
EXPECT_EQ(res, 0);
}
TEST(Utilities, VerifySignedIdentityKeys)
{
auto alice = olm_new_account();
auto alice = make_shared<OlmClient>();
alice->create_new_account();
alice->create_new_utility();
json keys = identity_keys(alice);
json keys = alice->identity_keys();
auto msg = json({{"algorithms", {"m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"}},
{"device_id", "some_device"},
......@@ -59,47 +63,16 @@ TEST(Utilities, VerifySignedIdentityKeys)
{"ed25519:some_device", keys["ed25519"]}}}})
.dump();
auto sig_buf = sign_message(alice, msg);
olm::Utility utillity;
auto sig_buf = alice->sign_message(msg);
auto res = utillity.ed25519_verify(alice->identity_keys.ed25519_key.public_key,
str_to_buffer(msg)->data(),
msg.size(),
sig_buf->data(),
SIGNATURE_SIZE);
auto res = olm_ed25519_verify(alice->utility(),
str_to_buffer(alice->identity_keys().ed25519)->data(),
str_to_buffer(alice->identity_keys().ed25519)->size(),
str_to_buffer(msg)->data(),
str_to_buffer(msg)->size(),
sig_buf->data(),
sig_buf->size());
EXPECT_EQ(utillity.last_error, 0);
EXPECT_EQ(std::string(olm_utility_last_error(alice->utility())), "SUCCESS");
EXPECT_EQ(res, 0);
}
TEST(Utilities, OutboundGroupSession)
{
auto alice = olm_new_account();
auto bob = olm_new_account();
auto carl = olm_new_account();
generate_one_time_keys(bob, 1);
generate_one_time_keys(carl, 1);
OneTimeKeys bob_otk = one_time_keys(bob);
IdentityKeys bob_ik = identity_keys(bob);
OneTimeKeys carl_otk = one_time_keys(carl);
IdentityKeys carl_ik = identity_keys(carl);
auto bob_session =
init_outbound_group_session(alice, bob_ik.curve25519, bob_otk.curve25519.begin()->second);
auto carl_session = init_outbound_group_session(
alice, carl_ik.curve25519, carl_otk.curve25519.begin()->second);
auto sid_1 = create_buffer(bob_session.session_id_length());
bob_session.session_id(sid_1->data(), sid_1->size());
EXPECT_EQ(sid_1->size(), 32);
auto sid_2 = create_buffer(carl_session.session_id_length());
carl_session.session_id(sid_2->data(), sid_2->size());
EXPECT_EQ(sid_2->size(), 32);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment