Add support for BASE64 encoded '|' when decrypting

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
This commit is contained in:
Kevin Ottens 2020-08-10 12:45:32 +02:00
Родитель 595eb78c8a
Коммит ef3c516598
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 074BBBCB8DECC9E2
2 изменённых файлов: 70 добавлений и 10 удалений

Просмотреть файл

@ -61,6 +61,31 @@ namespace {
const char e2e_cert[] = "_e2e-certificate";
const char e2e_private[] = "_e2e-private";
const char e2e_mnemonic[] = "_e2e-mnemonic";
QList<QByteArray> oldCipherFormatSplit(const QByteArray &cipher)
{
const auto separator = QByteArrayLiteral("fA=="); // BASE64 encoded '|'
auto result = QList<QByteArray>();
auto data = cipher;
auto index = data.indexOf(separator);
while (index >=0) {
result.append(data.left(index));
data = data.mid(index + separator.size());
index = data.indexOf(separator);
}
result.append(data);
return result;
}
QList<QByteArray> splitCipherParts(const QByteArray &data)
{
const auto isOldFormat = !data.contains('|');
const auto parts = isOldFormat ? oldCipherFormatSplit(data) : data.split('|');
qCInfo(lcCse()) << "found parts:" << parts << "old format?" << isOldFormat;
return parts;
}
} // ns
namespace {
@ -371,9 +396,7 @@ QByteArray decryptPrivateKey(const QByteArray& key, const QByteArray& data) {
qCInfo(lcCse()) << "decryptStringSymmetric key: " << key;
qCInfo(lcCse()) << "decryptStringSymmetric data: " << data;
const auto parts = data.split('|');
qCInfo(lcCse()) << "found parts:" << parts;
const auto parts = splitCipherParts(data);
if (parts.size() < 2) {
qCInfo(lcCse()) << "Not enough parts found";
return QByteArray();
@ -450,9 +473,7 @@ QByteArray decryptPrivateKey(const QByteArray& key, const QByteArray& data) {
QByteArray extractPrivateKeySalt(const QByteArray &data)
{
const auto parts = data.split('|');
qCInfo(lcCse()) << "found parts:" << parts;
const auto parts = splitCipherParts(data);
if (parts.size() < 3) {
qCInfo(lcCse()) << "Not enough parts found";
return QByteArray();
@ -465,11 +486,14 @@ QByteArray decryptStringSymmetric(const QByteArray& key, const QByteArray& data)
qCInfo(lcCse()) << "decryptStringSymmetric key: " << key;
qCInfo(lcCse()) << "decryptStringSymmetric data: " << data;
int sep = data.indexOf('|');
qCInfo(lcCse()) << "sep at" << sep;
const auto parts = splitCipherParts(data);
if (parts.size() < 2) {
qCInfo(lcCse()) << "Not enough parts found";
return QByteArray();
}
QByteArray cipherTXT64 = data.left(sep);
QByteArray ivB64 = data.right(data.size() - sep - 1);
QByteArray cipherTXT64 = parts.at(0);
QByteArray ivB64 = parts.at(1);
qCInfo(lcCse()) << "decryptStringSymmetric cipherTXT: " << cipherTXT64;
qCInfo(lcCse()) << "decryptStringSymmetric IV: " << ivB64;

Просмотреть файл

@ -14,6 +14,11 @@ class TestClientSideEncryption : public QObject
{
Q_OBJECT
QByteArray convertToOldStorageFormat(const QByteArray &data)
{
return data.split('|').join("fA==");
}
private slots:
void shouldEncryptPrivateKeys()
{
@ -59,6 +64,23 @@ private slots:
QCOMPARE(salt, originalSalt);
}
void shouldDecryptPrivateKeysInOldStorageFormat()
{
// GIVEN
const auto encryptionKey = QByteArrayLiteral("foo");
const auto originalPrivateKey = QByteArrayLiteral("bar");
const auto originalSalt = QByteArrayLiteral("baz");
const auto cipher = convertToOldStorageFormat(EncryptionHelper::encryptPrivateKey(encryptionKey, originalPrivateKey, originalSalt));
// WHEN
const auto privateKey = EncryptionHelper::decryptPrivateKey(encryptionKey, cipher);
const auto salt = EncryptionHelper::extractPrivateKeySalt(cipher);
// THEN
QCOMPARE(privateKey, originalPrivateKey);
QCOMPARE(salt, originalSalt);
}
void shouldSymmetricEncryptStrings()
{
// GIVEN
@ -96,6 +118,20 @@ private slots:
// THEN
QCOMPARE(data, originalData);
}
void shouldSymmetricDecryptStringsInOldStorageFormat()
{
// GIVEN
const auto encryptionKey = QByteArrayLiteral("foo");
const auto originalData = QByteArrayLiteral("bar");
const auto cipher = convertToOldStorageFormat(EncryptionHelper::encryptStringSymmetric(encryptionKey, originalData));
// WHEN
const auto data = EncryptionHelper::decryptStringSymmetric(encryptionKey, cipher);
// THEN
QCOMPARE(data, originalData);
}
};
QTEST_APPLESS_MAIN(TestClientSideEncryption)