Browse Source

Add unit tests for the encryption helpers

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
Kevin Ottens 5 years ago
parent
commit
26b88131cc
3 changed files with 105 additions and 4 deletions
  1. 4 4
      src/libsync/clientsideencryption.h
  2. 1 0
      test/CMakeLists.txt
  3. 100 0
      test/testclientsideencryption.cpp

+ 4 - 4
src/libsync/clientsideencryption.h

@@ -29,20 +29,20 @@ namespace EncryptionHelper {
     QByteArray generateRandomFilename();
     QByteArray generateRandom(int size);
     QByteArray generatePassword(const QString &wordlist, const QByteArray& salt);
-    QByteArray encryptPrivateKey(
+    OWNCLOUDSYNC_EXPORT QByteArray encryptPrivateKey(
             const QByteArray& key,
             const QByteArray& privateKey,
             const QByteArray &salt
     );
-    QByteArray decryptPrivateKey(
+    OWNCLOUDSYNC_EXPORT QByteArray decryptPrivateKey(
             const QByteArray& key,
             const QByteArray& data
     );
-    QByteArray encryptStringSymmetric(
+    OWNCLOUDSYNC_EXPORT QByteArray encryptStringSymmetric(
             const QByteArray& key,
             const QByteArray& data
     );
-    QByteArray decryptStringSymmetric(
+    OWNCLOUDSYNC_EXPORT QByteArray decryptStringSymmetric(
             const QByteArray& key,
             const QByteArray& data
     );

+ 1 - 0
test/CMakeLists.txt

@@ -40,6 +40,7 @@ nextcloud_add_test(ConcatUrl "")
 nextcloud_add_test(XmlParse "")
 nextcloud_add_test(ChecksumValidator "")
 
+nextcloud_add_test(ClientSideEncryption "")
 nextcloud_add_test(ExcludedFiles "")
 
 nextcloud_add_test(FileSystem "")

+ 100 - 0
test/testclientsideencryption.cpp

@@ -0,0 +1,100 @@
+/*
+   This software is in the public domain, furnished "as is", without technical
+   support, and with no warranty, express or implied, as to its usefulness for
+   any purpose.
+*/
+
+#include <QtTest>
+
+#include "clientsideencryption.h"
+
+using namespace OCC;
+
+class TestClientSideEncryption : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void shouldEncryptPrivateKeys()
+    {
+        // GIVEN
+        const auto encryptionKey = QByteArrayLiteral("foo");
+        const auto privateKey = QByteArrayLiteral("bar");
+        const auto originalSalt = QByteArrayLiteral("baz");
+
+        // WHEN
+        const auto cipher = EncryptionHelper::encryptPrivateKey(encryptionKey, privateKey, originalSalt);
+
+        // THEN
+        const auto parts = cipher.split('|');
+        QCOMPARE(parts.size(), 3);
+
+        const auto encryptedKey = QByteArray::fromBase64(parts[0]);
+        const auto iv = QByteArray::fromBase64(parts[1]);
+        const auto salt = QByteArray::fromBase64(parts[2]);
+
+        // We're not here to check the merits of the encryption but at least make sure it's been
+        // somewhat ciphered
+        QVERIFY(!encryptedKey.isEmpty());
+        QVERIFY(encryptedKey != privateKey);
+
+        QVERIFY(!iv.isEmpty());
+        QCOMPARE(salt, originalSalt);
+    }
+
+    void shouldDecryptPrivateKeys()
+    {
+        // GIVEN
+        const auto encryptionKey = QByteArrayLiteral("foo");
+        const auto originalPrivateKey = QByteArrayLiteral("bar");
+        const auto originalSalt = QByteArrayLiteral("baz");
+        const auto cipher = EncryptionHelper::encryptPrivateKey(encryptionKey, originalPrivateKey, originalSalt);
+
+        // WHEN (note the salt is not passed, so had to extract by hand)
+        const auto privateKey = EncryptionHelper::decryptPrivateKey(encryptionKey, cipher.left(cipher.lastIndexOf('|')));
+
+        // THEN
+        QCOMPARE(privateKey, originalPrivateKey);
+    }
+
+    void shouldSymmetricEncryptStrings()
+    {
+        // GIVEN
+        const auto encryptionKey = QByteArrayLiteral("foo");
+        const auto data = QByteArrayLiteral("bar");
+
+        // WHEN
+        const auto cipher = EncryptionHelper::encryptStringSymmetric(encryptionKey, data);
+
+        // THEN
+        const auto parts = cipher.split('|');
+        QCOMPARE(parts.size(), 2);
+
+        const auto encryptedData = QByteArray::fromBase64(parts[0]);
+        const auto iv = QByteArray::fromBase64(parts[1]);
+
+        // We're not here to check the merits of the encryption but at least make sure it's been
+        // somewhat ciphered
+        QVERIFY(!encryptedData.isEmpty());
+        QVERIFY(encryptedData != data);
+
+        QVERIFY(!iv.isEmpty());
+    }
+
+    void shouldSymmetricDecryptStrings()
+    {
+        // GIVEN
+        const auto encryptionKey = QByteArrayLiteral("foo");
+        const auto originalData = QByteArrayLiteral("bar");
+        const auto cipher = EncryptionHelper::encryptStringSymmetric(encryptionKey, originalData);
+
+        // WHEN (not it is still in base64 when returned)
+        const auto data = QByteArray::fromBase64(EncryptionHelper::decryptStringSymmetric(encryptionKey, cipher));
+
+        // THEN
+        QCOMPARE(data, originalData);
+    }
+};
+
+QTEST_APPLESS_MAIN(TestClientSideEncryption)
+#include "testclientsideencryption.moc"