From f59ab456441c4fbe304872391316010b4c06938b Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Mon, 2 Sep 2013 03:17:23 +0200 Subject: [PATCH] Support encrypting strings longer than key.maximumEncryptSize() Strings are divided in smaller chunks and serialized in an array Added a test for this case --- daemon/daemon.cpp | 2 +- daemon/networkpackage.cpp | 32 ++++++++++++++++++++++++-------- tests/networkpackagetests.cpp | 21 ++++++++++++++++++++- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/daemon/daemon.cpp b/daemon/daemon.cpp index 29e3274bb..b7f6cb443 100644 --- a/daemon/daemon.cpp +++ b/daemon/daemon.cpp @@ -56,7 +56,7 @@ Daemon::Daemon(QObject *parent, const QList&) if (!config->group("myself").hasKey("privateKey") || !config->group("myself").hasKey("publicKey")) { //http://delta.affinix.com/docs/qca/rsatest_8cpp-example.html - QCA::PrivateKey privateKey = QCA::KeyGenerator().createRSA(1024); + QCA::PrivateKey privateKey = QCA::KeyGenerator().createRSA(2048); config->group("myself").writeEntry("privateKey", privateKey.toDER().toByteArray().toBase64()); QCA::PublicKey publicKey = privateKey.toPublicKey(); diff --git a/daemon/networkpackage.cpp b/daemon/networkpackage.cpp index c0077faf9..9277ff88c 100644 --- a/daemon/networkpackage.cpp +++ b/daemon/networkpackage.cpp @@ -90,15 +90,25 @@ void NetworkPackage::unserialize(const QByteArray& a, NetworkPackage* np) void NetworkPackage::encrypt (QCA::PublicKey& key) { - qDebug() << key.toDER() << key.canEncrypt(); - + QByteArray serialized = serialize(); - QByteArray data = key.encrypt(serialized, QCA::EME_PKCS1v15).toByteArray(); + + int chunkSize = key.maximumEncryptSize(QCA::EME_PKCS1v15); + + QStringList chunks; + while (!serialized.isEmpty()) { + QByteArray chunk = serialized.left(chunkSize); + serialized = serialized.mid(chunkSize); + QByteArray encryptedChunk = key.encrypt(chunk, QCA::EME_PKCS1v15).toByteArray(); + chunks.append( encryptedChunk.toBase64() ); + } + + qDebug() << chunks.size() << "chunks"; mId = QString::number(QDateTime::currentMSecsSinceEpoch()); mType = "kdeconnect.encrypted"; mBody = QVariantMap(); - mBody["data"] = data.toBase64(); + mBody["data"] = chunks; mVersion = CURRENT_PACKAGE_VERSION; mEncrypted = true; @@ -106,12 +116,18 @@ void NetworkPackage::encrypt (QCA::PublicKey& key) void NetworkPackage::decrypt (QCA::PrivateKey& key, NetworkPackage* out) const { - QByteArray encryptedJson = QByteArray::fromBase64(get("data")); + const QStringList& chunks = mBody["data"].toStringList(); - QCA::SecureArray decryptedJson; - key.decrypt(encryptedJson, &decryptedJson, QCA::EME_PKCS1v15); + QByteArray decryptedJson; + Q_FOREACH(const QString& chunk, chunks) { + QByteArray encryptedChunk = QByteArray::fromBase64(chunk.toAscii()); + QCA::SecureArray decryptedChunk; + key.decrypt(encryptedChunk, &decryptedChunk, QCA::EME_PKCS1v15); + decryptedJson.append(decryptedChunk.toByteArray()); - unserialize(decryptedJson.toByteArray(), out); + } + + unserialize(decryptedJson, out); } diff --git a/tests/networkpackagetests.cpp b/tests/networkpackagetests.cpp index 8b054145f..4ac834480 100644 --- a/tests/networkpackagetests.cpp +++ b/tests/networkpackagetests.cpp @@ -39,6 +39,8 @@ void NetworkPackageTests::dummyTest() QVERIFY( date.isValid() ); QCOMPARE( date.month(), 3 ); QCOMPARE( QDate::longMonthName(date.month()), QString("March") ); + + QCOMPARE(QString("hello").toUpper(), QString("HELLO")); } void NetworkPackageTests::networkPackageTest() @@ -93,9 +95,10 @@ void NetworkPackageTests::networkPackageEncryptionTest() NetworkPackage decrypted(""); QCA::Initializer init; - QCA::PrivateKey privateKey = QCA::KeyGenerator().createRSA(1024); + QCA::PrivateKey privateKey = QCA::KeyGenerator().createRSA(2048); QCA::PublicKey publicKey = privateKey.toPublicKey(); + //Encrypt and decrypt np QCOMPARE( original.isEncrypted(), false ); original.encrypt(publicKey); @@ -110,6 +113,22 @@ void NetworkPackageTests::networkPackageEncryptionTest() QCOMPARE( decrypted.version(), copy.version() ); QCOMPARE( decrypted.body(), copy.body() ); + + + //Test for long package encryption that need multi-chunk encryption + + QByteArray json = "{ \"body\" : { \"nowPlaying\" : \"A really long song name - A really long artist name\", \"player\" : \"A really long player name\" }, \"id\" : \"A really long package id\", \"isEncrypted\" : false, \"type\" : \"kdeconnect.a_really_long_package_type\", \"version\" : 2 }\n"; + qDebug() << "EME_PKCS1_OAEP maximumEncryptSize" << publicKey.maximumEncryptSize(QCA::EME_PKCS1_OAEP); + qDebug() << "EME_PKCS1v15 maximumEncryptSize" << publicKey.maximumEncryptSize(QCA::EME_PKCS1v15); + QCOMPARE( json.size() > publicKey.maximumEncryptSize(QCA::EME_PKCS1v15), true ); + + NetworkPackage::unserialize(json, &original); + original.encrypt(publicKey); + original.decrypt(privateKey, &decrypted); + QByteArray decryptedJson = decrypted.serialize(); + + QCOMPARE(QString(json), QString(decryptedJson)); + }