/* * Created by victoria on 2021-05-13. */ #include "database.h" #include "bundle.h" #include #include #include #include #include using namespace QXmpp::Omemo; Database::Database(QString jid) : jid(std::move(jid)) { auto cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); auto path = QString("%1/.omemo/%2").arg(cacheLocation, jid); QDir cache(path); if (!cache.exists() && !cache.mkpath(path)) { qWarning() << "Could not create:" << path; throw QException(); } mdb_env_create(&env); mdb_env_set_maxdbs(env, 5); mdb_env_set_mapsize(env, 512UL * 1024UL * 1024UL); mdb_env_open(env, path.toStdString().c_str(), 0, 0664); MDB_txn *txn; mdb_txn_begin(env, nullptr, 0, &txn); mdb_dbi_open(txn, "keys", MDB_CREATE, &dbiKeys); mdb_dbi_open(txn, "devices", MDB_CREATE, &dbiDevices); mdb_dbi_open(txn, "identity_keys", MDB_CREATE, &dbiIdentityKeys); mdb_txn_commit(txn); } Database::~Database() { mdb_dbi_close(env, dbiKeys); mdb_dbi_close(env, dbiDevices); mdb_dbi_close(env, dbiIdentityKeys); mdb_env_close(env); } std::optional Database::loadIdentityKeySecret(int deviceId) { return std::nullopt; } bool Database::saveIdentityKeySecret(int deviceId, const QByteArray &identityKeySecret) { MDB_val mdbKey, mdbValue; auto key = QString("%1/secret").arg(QString::number(deviceId)).toStdString(); mdbKey.mv_data = key.data(); mdbKey.mv_size = key.size(); mdbValue.mv_data = const_cast(identityKeySecret.data()); mdbValue.mv_size = identityKeySecret.size(); MDB_txn *txn; mdb_txn_begin(env, nullptr, 0, &txn); auto err = mdb_put(txn, dbiIdentityKeys, &mdbKey, &mdbValue, MDB_NOOVERWRITE); if (!err) { mdb_txn_commit(txn); return true; } qWarning() << "could not save identity key secret:" << mdb_strerror(err); mdb_txn_abort(txn); return false; } std::optional Database::loadActiveDeviceId() { MDB_val key, value; key.mv_data = (void *) "active"; key.mv_size = sizeof("active"); MDB_txn *txn; mdb_txn_begin(env, nullptr, 0, &txn); auto err = mdb_get(txn, dbiIdentityKeys, &key, &value); if (err) { qWarning() << "could not load active device id:" << mdb_strerror(err); mdb_txn_abort(txn); return std::nullopt; } if (value.mv_size != sizeof(int)) { qWarning() << "mv_size is" << value.mv_size << "instead of" << sizeof(int); mdb_txn_abort(txn); return std::nullopt; } auto id = *reinterpret_cast(value.mv_data); mdb_txn_abort(txn); return id; } bool Database::saveActiveDeviceId(int deviceId) { MDB_val key, value; key.mv_data = (void *) "active"; key.mv_size = sizeof("active"); value.mv_data = &deviceId; value.mv_size = sizeof(deviceId); MDB_txn *txn; mdb_txn_begin(env, nullptr, 0, &txn); auto err = mdb_put(txn, dbiIdentityKeys, &key, &value, 0); if (err) { qWarning() << "could not save active device id" << mdb_strerror(err); return false; } err = mdb_txn_commit(txn); if (err) { qWarning() << "could not save active device id" << mdb_strerror(err); return false; } return true; } bool Database::saveIdentityKey(int deviceId, const QByteArray &identityKey) { return false; } std::optional Database::loadIdentityKey(int deviceId) { return std::nullopt; } bool Database::containsPreKey() { return false; } std::optional Database::loadPreKey(int deviceId, int id) { return std::nullopt; } bool Database::savePreKey(int deviceId, int id, const KeyPair &preKey) { return false; } std::optional Database::loadBundle(int deviceId) { Bundle result{}; auto ik = loadIdentityKey(deviceId); result.ik = ik.value(); auto spk = loadSignedPreKey(deviceId); result.spk = spk->key.publicKey; result.spks = spk->signature; result.spkId = spk->id; // PreKeys return result; } bool Database::saveBundle(int deviceId, const Bundle &bundle) { return false; } std::optional Database::loadSignedPreKey(int deviceId) { return std::optional(); } bool Database::saveSignedPreKey(int deviceId, const SignedPreKey &signedPreKey) { return false; }