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.
This commit is contained in:
parent
d1f38a16b2
commit
42e0b4a066
6 changed files with 87 additions and 42 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
bool LanDeviceLink::sendPackage(NetworkPackage& np)
|
||||
{
|
||||
int written = mSocket->write(np.serialize());
|
||||
return written != -1;
|
||||
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) {
|
||||
|
||||
Q_EMIT receivedPackage(np);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue