Commit 42e0b4a0 authored by Albert Vaca Cintora's avatar Albert Vaca Cintora

Moved cryptography layer down from Device to DeviceLink

DeviceLinks will need to know what they are sending and receiving to handle
payloads, so encryption can not happen above them.
parent d1f38a16
......@@ -22,6 +22,7 @@
#define DEVICELINK_H
#include <QObject>
#include <QtCrypto>
#include "../networkpackage.h"
......@@ -39,15 +40,21 @@ public:
const QString& deviceId() { return mDeviceId; }
LinkProvider* provider() { return mLinkProvider; }
virtual bool sendPackage(const NetworkPackage& np) = 0;
virtual bool sendPackage(NetworkPackage& np) = 0;
virtual bool sendPackageEncrypted(QCA::PublicKey& publicKey, NetworkPackage& np) = 0;
void setPrivateKey(const QCA::PrivateKey& privateKey) { mPrivateKey = privateKey; }
Q_SIGNALS:
void receivedPackage(const NetworkPackage& np);
protected:
QCA::PrivateKey mPrivateKey;
private:
QString mDeviceId;
LinkProvider* mLinkProvider;
};
#endif // DEVICELINK_H
#endif
......@@ -51,10 +51,17 @@ LanDeviceLink::LanDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* sock
this, SLOT(dataReceived()));
}
bool LanDeviceLink::sendPackage(const NetworkPackage& np)
bool LanDeviceLink::sendPackageEncrypted(QCA::PublicKey& key, NetworkPackage& np)
{
np.encrypt(key);
int written = mSocket->write(np.serialize());
return written != -1;
return (written != -1);
}
bool LanDeviceLink::sendPackage(NetworkPackage& np)
{
int written = mSocket->write(np.serialize());
return (written != -1);
}
void LanDeviceLink::dataReceived()
......@@ -67,10 +74,24 @@ void LanDeviceLink::dataReceived()
if (package.length() < 3) continue;
NetworkPackage np("");
NetworkPackage np(QString::null);
NetworkPackage::unserialize(package, &np);
if (np.type() == PACKAGE_TYPE_ENCRYPTED) {
if (mPrivateKey.isNull()) {
//TODO: Emit the problem?
return;
}
NetworkPackage decrypted(QString::null);
np.decrypt(mPrivateKey, &decrypted);
Q_EMIT receivedPackage(decrypted);
} else {
Q_EMIT receivedPackage(np);
Q_EMIT receivedPackage(np);
}
}
}
......@@ -37,7 +37,8 @@ class LanDeviceLink
public:
LanDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* socket);
bool sendPackage(const NetworkPackage& np);
bool sendPackage(NetworkPackage& np);
bool sendPackageEncrypted(QCA::PublicKey& key, NetworkPackage& np);
private Q_SLOTS:
void dataReceived();
......
......@@ -28,7 +28,34 @@ LoopbackDeviceLink::LoopbackDeviceLink(const QString& deviceId, LoopbackLinkProv
}
bool LoopbackDeviceLink::sendPackage(const NetworkPackage& input)
bool LoopbackDeviceLink::sendPackageEncrypted(QCA::PublicKey& key, NetworkPackage& input)
{
if (mPrivateKey.isNull() || key.isNull()) {
return false;
}
input.encrypt(key);
QByteArray serialized = input.serialize();
NetworkPackage unserialized(QString::null);
NetworkPackage::unserialize(serialized, &unserialized);
NetworkPackage output(QString::null);
unserialized.decrypt(mPrivateKey, &output);
//LoopbackDeviceLink does not need deviceTransferInfo
if (input.hasPayload()) {
QIODevice* device = input.payload();
output.setPayload(device);
}
Q_EMIT receivedPackage(output);
return true;
}
bool LoopbackDeviceLink::sendPackage(NetworkPackage& input)
{
NetworkPackage output(QString::null);
NetworkPackage::unserialize(input.serialize(), &output);
......@@ -43,3 +70,4 @@ bool LoopbackDeviceLink::sendPackage(const NetworkPackage& input)
return true;
}
......@@ -32,7 +32,8 @@ class LoopbackDeviceLink
public:
LoopbackDeviceLink(const QString& d, LoopbackLinkProvider* a);
bool sendPackage(const NetworkPackage& np);
virtual bool sendPackage(NetworkPackage& np);
virtual bool sendPackageEncrypted(QCA::PublicKey& publicKey, NetworkPackage& np);
};
......
......@@ -202,6 +202,12 @@ void Device::addLink(DeviceLink* link)
m_deviceLinks.append(link);
//TODO: Do not read the key every time
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
const QString& key = config->group("myself").readEntry<QString>("privateKey",QString());
QCA::PrivateKey privateKey = QCA::PrivateKey::fromPEM(key);
link->setPrivateKey(privateKey);
//Theoretically we will never add two links from the same provider (the provider should destroy
//the old one before this is called), so we do not have to worry about destroying old links.
//Actually, we should not destroy them or the provider will store an invalid ref!
......@@ -241,17 +247,22 @@ void Device::removeLink(DeviceLink* link)
bool Device::sendPackage(NetworkPackage& np)
{
if (np.type() != PACKAGE_TYPE_PAIR && isPaired()) {
np.encrypt(m_publicKey);
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
//TODO: Actually detect if a package is received or not, now we keep TCP
//"ESTABLISHED" connections that look legit (return true when we use them),
//but that are actually broken
if (dl->sendPackageEncrypted(m_publicKey, np)) return true;
}
} else {
//Maybe we could block here any package that is not an identity or a pairing package to prevent sending non encrypted data
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
//TODO: Actually detect if a package is received or not, now we keep TCP
//"ESTABLISHED" connections that look legit (return true when we use them),
//but that are actually broken
if (dl->sendPackage(np)) return true;
}
}
Q_FOREACH(DeviceLink* dl, m_deviceLinks) {
//TODO: Actually detect if a package is received or not, now we keep TCP
//"ESTABLISHED" connections that look legit (return true when we use them),
//but that are actually broken
if (dl->sendPackage(np)) return true;
}
return false;
}
......@@ -346,32 +357,8 @@ void Device::privateReceivedPackage(const NetworkPackage& np)
} else {
if (np.type() == PACKAGE_TYPE_ENCRYPTED) {
//TODO: Do not read the key every time
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
const QString& key = config->group("myself").readEntry<QString>("privateKey",QString());
QCA::PrivateKey privateKey = QCA::PrivateKey::fromPEM(key);
//Emit decrypted package
NetworkPackage decryptedNp("");
bool success = np.decrypt(privateKey, &decryptedNp);
if (!success) {
qDebug() << "Failed to decrypt package";
} else {
Q_EMIT receivedPackage(decryptedNp);
}
} else {
//TODO: The other side doesn't know that we are already paired, do something
qDebug() << "WARNING: Received unencrypted package from paired device!";
//Forward package
Q_EMIT receivedPackage(np);
}
//Forward package
Q_EMIT receivedPackage(np);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment