Browse Source

Merge branch 'corencryption' into history, remove file encryption, store key instead of hash

(I forgot to commit the merge before starting work...)

Conflicts:
	qtox.pro
pull/423/head
dubslow 11 years ago
parent
commit
041ed3b998
  1. 2
      bootstrap.sh
  2. 4
      qtox.pro
  3. 106
      src/core.cpp
  4. 7
      src/core.h
  5. 10
      src/misc/settings.cpp
  6. 4
      src/misc/settings.h
  7. 12
      src/widget/widget.cpp
  8. 1
      src/widget/widget.h

2
bootstrap.sh

@ -10,7 +10,7 @@ INSTALL_DIR=libs
# just for convenience # just for convenience
BASE_DIR=${SCRIPT_DIR}/${INSTALL_DIR} BASE_DIR=${SCRIPT_DIR}/${INSTALL_DIR}
SODIUM_VER=0.7.0 SODIUM_VER=1.0.0
# directory names of cloned repositories # directory names of cloned repositories
SODIUM_DIR=libsodium-$SODIUM_VER SODIUM_DIR=libsodium-$SODIUM_VER

4
qtox.pro

@ -71,11 +71,11 @@ win32 {
LIBS += -Wl,-Bdynamic -ltbb -lv4l1 -lv4l2 -lgnutls -lrtmp -lgnutls -lavformat -lavcodec -lavutil -lavfilter -lswscale -lusb-1.0 LIBS += -Wl,-Bdynamic -ltbb -lv4l1 -lv4l2 -lgnutls -lrtmp -lgnutls -lavformat -lavcodec -lavutil -lavfilter -lswscale -lusb-1.0
} else { } else {
LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxencryptsave -ltoxav -lvpx -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -lvpx -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc
} }
contains(JENKINS, YES) { contains(JENKINS, YES) {
LIBS = ./libs/lib/libtoxav.a ./libs/lib/libtoxencryptsave.a ./libs/lib/libvpx.a ./libs/lib/libopus.a ./libs/lib/libtoxcore.a ./libs/lib/libsodium.a -lopencv_core -lopencv_highgui -lopenal LIBS = ./libs/lib/libsodium.a ./libs/lib/libtoxcore.a ./libs/lib/libtoxav.a ./libs/lib/libtoxencryptsave.a ./libs/lib/libvpx.a ./libs/lib/libopus.a -lopencv_core -lopencv_highgui -lopenal
} }
} }
} }

106
src/core.cpp

@ -21,6 +21,7 @@
#include "widget/widget.h" #include "widget/widget.h"
#include <tox/tox.h> #include <tox/tox.h>
#include <tox/toxencryptsave.h>
#include <ctime> #include <ctime>
#include <functional> #include <functional>
@ -113,6 +114,8 @@ Core::~Core()
alcCloseDevice(alOutDev); alcCloseDevice(alOutDev);
if (alInDev) if (alInDev)
alcCaptureCloseDevice(alInDev); alcCaptureCloseDevice(alInDev);
clearPassword();
} }
Core* Core::getInstance() Core* Core::getInstance()
@ -1099,6 +1102,8 @@ bool Core::loadConfiguration(QString path)
qWarning() << "Core: tox_load failed with error "<<error; qWarning() << "Core: tox_load failed with error "<<error;
} }
else if (error == 1) // Encrypted data save else if (error == 1) // Encrypted data save
{
if (!pwsaltedkey)
{ {
qWarning() << "Core: Can not open encrypted tox save"; qWarning() << "Core: Can not open encrypted tox save";
if (QMessageBox::Ok != QMessageBox::warning(nullptr, tr("Encrypted profile"), if (QMessageBox::Ok != QMessageBox::warning(nullptr, tr("Encrypted profile"),
@ -1110,6 +1115,17 @@ bool Core::loadConfiguration(QString path)
return false; return false;
} }
} }
else
{ /*
while (error != 0)
{
error = tox_encrypted_load(tox, reinterpret_cast<uint8_t *>(data.data()), data.size(), pwsaltedkey, TOX_HASH_LENGTH);
emit blockingGetPassword();
if (!pwsaltedkey)
// we need a way to start core without any profile
} */
}
}
} }
configurationFile.close(); configurationFile.close();
@ -1137,22 +1153,18 @@ void Core::saveConfiguration()
} }
QString profile = Settings::getInstance().getCurrentProfile(); QString profile = Settings::getInstance().getCurrentProfile();
//qDebug() << "saveConf read profile: " << profile;
if (profile == "") if (profile == "")
{ // no profile active; this should only happen on startup, if at all { // no profile active; this should only happen on startup, if at all
profile = sanitize(getUsername()); profile = sanitize(getUsername());
if (profile == "") // happens on creation of a new Tox ID if (profile == "") // happens on creation of a new Tox ID
profile = getIDString(); profile = getIDString();
//qDebug() << "saveConf: read sanitized user as " << profile;
Settings::getInstance().setCurrentProfile(profile); Settings::getInstance().setCurrentProfile(profile);
} }
QString path = dir + QDir::separator() + profile + TOX_EXT; QString path = directory.filePath(profile + TOX_EXT);
QFileInfo info(path);
// if (!info.exists()) // fall back to old school 'data'
// { //path = dir + QDir::separator() + CONFIG_FILE_NAME;
// qDebug() << "Core:" << path << " does not exist";
// }
saveConfiguration(path); saveConfiguration(path);
} }
@ -1174,10 +1186,32 @@ void Core::saveConfiguration(const QString& path)
} }
qDebug() << "Core: writing tox_save to " << path; qDebug() << "Core: writing tox_save to " << path;
uint32_t fileSize = tox_size(tox);
uint32_t fileSize;
if (Settings::getInstance().getEncryptTox())
fileSize = tox_encrypted_size(tox);
else
fileSize = tox_size(tox);
if (fileSize > 0 && fileSize <= INT32_MAX) { if (fileSize > 0 && fileSize <= INT32_MAX) {
uint8_t *data = new uint8_t[fileSize]; uint8_t *data = new uint8_t[fileSize];
if (Settings::getInstance().getEncryptTox())
{
if (!pwsaltedkey)
emit blockingGetPassword();
//if (!pwsaltedkey)
// revert to unsaved...? or maybe we shouldn't even try to get a pw from here ^
int ret = tox_encrypted_save(tox, data, pwsaltedkey, TOX_HASH_LENGTH);
if (ret == -1)
{
qCritical() << "Core::saveConfiguration: encryption of save file failed!!!";
return;
}
}
else
tox_save(tox, data); tox_save(tox, data);
configurationFile.write(reinterpret_cast<char *>(data), fileSize); configurationFile.write(reinterpret_cast<char *>(data), fileSize);
configurationFile.commit(); configurationFile.commit();
delete[] data; delete[] data;
@ -1193,8 +1227,9 @@ void Core::switchConfiguration(const QString& profile)
} }
else else
qDebug() << "Core: switching from" << Settings::getInstance().getCurrentProfile() << "to" << profile; qDebug() << "Core: switching from" << Settings::getInstance().getCurrentProfile() << "to" << profile;
saveConfiguration();
saveConfiguration();
clearPassword();
toxTimer->stop(); toxTimer->stop();
if (tox) { if (tox) {
@ -1488,3 +1523,54 @@ QList<CString> Core::splitMessage(const QString &message)
return splittedMsgs; return splittedMsgs;
} }
void Core::setPassword(QString& password)
{
if (password.isEmpty())
{
clearPassword();
return;
}
if (!pwsaltedkey)
pwsaltedkey = new uint8_t[tox_pass_key_length()];
CString str(password);
tox_derive_key_from_pass(str.data(), str.size(), pwsaltedkey);
password.clear();
}
void Core::clearPassword()
{
if (pwsaltedkey)
{
delete[] pwsaltedkey;
pwsaltedkey = nullptr;
}
}
QByteArray Core::encryptData(const QByteArray& data)
{
if (!pwsaltedkey)
return QByteArray();
uint8_t encrypted[data.size() + tox_pass_encryption_extra_length()];
if (tox_pass_key_encrypt(reinterpret_cast<const uint8_t*>(data.data()), data.size(), pwsaltedkey, encrypted) == -1)
{
qWarning() << "Core::encryptData: encryption failed";
return QByteArray();
}
return QByteArray(reinterpret_cast<char*>(encrypted), data.size() + tox_pass_encryption_extra_length());
}
QByteArray Core::decryptData(const QByteArray& data)
{
if (!pwsaltedkey)
return QByteArray();
int sz = data.size() - tox_pass_encryption_extra_length();
uint8_t decrypted[sz];
if (tox_pass_key_decrypt(reinterpret_cast<const uint8_t*>(data.data()), data.size(), pwsaltedkey, decrypted) != sz)
{
qWarning() << "Core::decryptData: decryption failed";
return QByteArray();
}
return QByteArray(reinterpret_cast<char*>(decrypted), sz);
}

7
src/core.h

@ -104,10 +104,16 @@ public slots:
void micMuteToggle(int callId); void micMuteToggle(int callId);
void setPassword(QString& password);
void clearPassword();
QByteArray encryptData(const QByteArray& data);
QByteArray decryptData(const QByteArray& data);
signals: signals:
void connected(); void connected();
void disconnected(); void disconnected();
void blockingClearContacts(); void blockingClearContacts();
void blockingGetPassword();
void friendRequestReceived(const QString& userId, const QString& message); void friendRequestReceived(const QString& userId, const QString& message);
void friendMessageReceived(int friendId, const QString& message, bool isAction); void friendMessageReceived(int friendId, const QString& message, bool isAction);
@ -244,6 +250,7 @@ private:
int dhtServerId; int dhtServerId;
static QList<ToxFile> fileSendQueue, fileRecvQueue; static QList<ToxFile> fileSendQueue, fileRecvQueue;
static ToxCall calls[]; static ToxCall calls[];
uint8_t* pwsaltedkey = nullptr; // use the pw's hash as the "pw"
static const int videobufsize; static const int videobufsize;
static uint8_t* videobuf; static uint8_t* videobuf;

10
src/misc/settings.cpp

@ -472,6 +472,16 @@ void Settings::setEncryptLogs(bool newValue)
encryptLogs = newValue; encryptLogs = newValue;
} }
bool Settings::getEncryptTox() const
{
return encryptTox;
}
void Settings::setEncryptTox(bool newValue)
{
encryptTox = newValue;
}
int Settings::getAutoAwayTime() const int Settings::getAutoAwayTime() const
{ {
return autoAwayTime; return autoAwayTime;

4
src/misc/settings.h

@ -79,6 +79,9 @@ public:
bool getEncryptLogs() const; bool getEncryptLogs() const;
void setEncryptLogs(bool newValue); void setEncryptLogs(bool newValue);
bool getEncryptTox() const;
void setEncryptTox(bool newValue);
int getAutoAwayTime() const; int getAutoAwayTime() const;
void setAutoAwayTime(int newValue); void setAutoAwayTime(int newValue);
@ -193,6 +196,7 @@ private:
bool enableLogging; bool enableLogging;
bool encryptLogs; bool encryptLogs;
bool encryptTox;
int autoAwayTime; int autoAwayTime;

12
src/widget/widget.cpp

@ -164,6 +164,7 @@ Widget::Widget(QWidget *parent)
connect(core, &Core::emptyGroupCreated, this, &Widget::onEmptyGroupCreated); connect(core, &Core::emptyGroupCreated, this, &Widget::onEmptyGroupCreated);
connect(core, &Core::avInvite, this, &Widget::playRingtone); connect(core, &Core::avInvite, this, &Widget::playRingtone);
connect(core, &Core::blockingClearContacts, this, &Widget::clearContactsList, Qt::BlockingQueuedConnection); connect(core, &Core::blockingClearContacts, this, &Widget::clearContactsList, Qt::BlockingQueuedConnection);
connect(core, &Core::blockingGetPassword, this, &Widget::getPassword, Qt::BlockingQueuedConnection);
connect(core, SIGNAL(messageSentResult(int,QString,int)), this, SLOT(onMessageSendResult(int,QString,int))); connect(core, SIGNAL(messageSentResult(int,QString,int)), this, SLOT(onMessageSendResult(int,QString,int)));
connect(core, SIGNAL(groupSentResult(int,QString,int)), this, SLOT(onGroupSendResult(int,QString,int))); connect(core, SIGNAL(groupSentResult(int,QString,int)), this, SLOT(onGroupSendResult(int,QString,int)));
@ -309,7 +310,7 @@ QString Widget::getUsername()
void Widget::onAvatarClicked() void Widget::onAvatarClicked()
{ {
QString filename = QFileDialog::getOpenFileName(this, tr("Choose a profile picture"), QDir::homePath()); QString filename = QFileDialog::getOpenFileName(this, tr("Choose a profile picture"), QDir::homePath());
if (filename == "") if (filename.isEmpty())
return; return;
QFile file(filename); QFile file(filename);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
@ -909,3 +910,12 @@ void Widget::onGroupSendResult(int groupId, const QString& message, int result)
if (result == -1) if (result == -1)
g->chatForm->addSystemInfoMessage("Message failed to send", "red", QDateTime::currentDateTime()); g->chatForm->addSystemInfoMessage("Message failed to send", "red", QDateTime::currentDateTime());
} }
void Widget::getPassword()
{
//QString password = QInputDialog();
//if (password.isEmpty())
// core->clearPassword();
//else
// core->setPassword(password);
}

1
src/widget/widget.h

@ -112,6 +112,7 @@ private slots:
void playRingtone(); void playRingtone();
void onIconClick(); void onIconClick();
void onUserAway(); void onUserAway();
void getPassword();
private: private:
void hideMainForms(); void hideMainForms();

Loading…
Cancel
Save