kdeconnect-kde/kded/networkpackage.cpp

157 lines
4.6 KiB
C++
Raw Normal View History

2013-06-06 04:57:06 +01:00
/**
* Copyright 2013 Albert Vaca <albertvaka@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "networkpackage.h"
#include <KSharedConfig>
#include <KConfigGroup>
#include <QByteArray>
#include <QDataStream>
#include <QHostInfo>
#include <QSslKey>
#include <QDateTime>
2013-09-08 18:06:13 +01:00
#include <QtCrypto>
#include <qjson/serializer.h>
#include <qjson/qobjecthelper.h>
2013-06-06 04:57:06 +01:00
2013-09-03 01:13:13 +01:00
const QCA::EncryptionAlgorithm NetworkPackage::EncryptionAlgorithm = QCA::EME_PKCS1v15;
const int NetworkPackage::ProtocolVersion = 4;
2013-09-03 01:13:13 +01:00
2013-08-07 12:40:39 +01:00
NetworkPackage::NetworkPackage(const QString& type)
{
mId = QString::number(QDateTime::currentMSecsSinceEpoch());
mType = type;
mBody = QVariantMap();
mPayload = 0;
}
void NetworkPackage::createIdentityPackage(NetworkPackage* np)
{
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
QString id = config->group("myself").readEntry<QString>("id","");
np->mId = QString::number(QDateTime::currentMSecsSinceEpoch());
np->mType = PACKAGE_TYPE_IDENTITY;
np->mPayload = 0;
np->set("deviceId", id);
np->set("deviceName", QHostInfo::localHostName());
np->set("protocolVersion", NetworkPackage::ProtocolVersion);
//qDebug() << "createIdentityPackage" << np->serialize();
}
QByteArray NetworkPackage::serialize() const
2013-06-06 04:57:06 +01:00
{
//Object -> QVariant
//QVariantMap variant;
//variant["id"] = mId;
//variant["type"] = mType;
//variant["body"] = mBody;
QVariantMap variant = QJson::QObjectHelper::qobject2qvariant(this);
if (hasPayload()) {
variant["payloadTransferInfo"] = mPayloadTransferInfo;
}
//QVariant -> json
bool ok;
QJson::Serializer serializer;
QByteArray json = serializer.serialize(variant,&ok);
if (!ok) {
qDebug() << "Serialization error:" << serializer.errorMessage();
} else {
//qDebug() << "Serialized package:" << json;
json.append('\n');
}
return json;
2013-06-06 04:57:06 +01:00
}
bool NetworkPackage::unserialize(const QByteArray& a, NetworkPackage* np)
2013-06-17 11:23:08 +01:00
{
//qDebug() << "Unserialize: " << a;
//Json -> QVariant
QJson::Parser parser;
bool ok;
QVariantMap variant = parser.parse(a, &ok).toMap();
if (!ok) {
qDebug() << "Unserialization error:" << parser.errorLine() << parser.errorString();
return false;
}
//QVariant -> Object
QJson::QObjectHelper::qvariant2qobject(variant,np);
if (variant.contains("payloadTransferInfo")) {
np->mPayloadTransferInfo = variant["payloadTransferInfo"].toMap();
}
return true;
2013-06-17 11:23:08 +01:00
}
void NetworkPackage::encrypt (QCA::PublicKey& key)
{
QByteArray serialized = serialize();
int chunkSize = key.maximumEncryptSize(NetworkPackage::EncryptionAlgorithm);
QStringList chunks;
while (!serialized.isEmpty()) {
QByteArray chunk = serialized.left(chunkSize);
serialized = serialized.mid(chunkSize);
QByteArray encryptedChunk = key.encrypt(chunk, NetworkPackage::EncryptionAlgorithm).toByteArray();
chunks.append( encryptedChunk.toBase64() );
}
2013-09-08 18:06:13 +01:00
//qDebug() << chunks.size() << "chunks";
mId = QString::number(QDateTime::currentMSecsSinceEpoch());
mType = PACKAGE_TYPE_ENCRYPTED;
mBody = QVariantMap();
mBody["data"] = chunks;
}
bool NetworkPackage::decrypt (QCA::PrivateKey& key, NetworkPackage* out) const
{
const QStringList& chunks = mBody["data"].toStringList();
QByteArray decryptedJson;
Q_FOREACH(const QString& chunk, chunks) {
QByteArray encryptedChunk = QByteArray::fromBase64(chunk.toAscii());
QCA::SecureArray decryptedChunk;
bool success = key.decrypt(encryptedChunk, &decryptedChunk, NetworkPackage::EncryptionAlgorithm);
if (!success) {
return false;
}
decryptedJson.append(decryptedChunk.toByteArray());
}
return unserialize(decryptedJson, out);
}