diff options
-rw-r--r-- | lib/connection.cpp | 3 | ||||
-rw-r--r-- | lib/encryptionmanager.cpp | 67 | ||||
-rw-r--r-- | lib/encryptionmanager.h | 3 |
3 files changed, 47 insertions, 26 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp index 20fb367c..ff066def 100644 --- a/lib/connection.cpp +++ b/lib/connection.cpp @@ -254,6 +254,9 @@ void Connection::doConnectToServer(const QString& user, const QString& password, AccountSettings accountSettings(loginJob->userId()); d->encryptionManager.reset(new EncryptionManager(accountSettings.encryptionAccountPickle())); + if (accountSettings.encryptionAccountPickle().isEmpty()) { + accountSettings.setEncryptionAccountPickle(d->encryptionManager->olmAccountPickle()); + } d->encryptionManager->uploadIdentityKeys(this); d->encryptionManager->uploadOneTimeKeys(this); diff --git a/lib/encryptionmanager.cpp b/lib/encryptionmanager.cpp index 1e1fc669..c2e244fc 100644 --- a/lib/encryptionmanager.cpp +++ b/lib/encryptionmanager.cpp @@ -24,13 +24,17 @@ class EncryptionManager::Private { public: explicit Private(const QByteArray& encryptionAccountPickle, float signedKeysProportion, float oneTimeKeyThreshold) - : olmAccount(new Account(encryptionAccountPickle)), // TODO: passphrase even with qtkeychain? - signedKeysProportion(move(signedKeysProportion)), - oneTimeKeyThreshold(move(oneTimeKeyThreshold)), - targetKeysNumber(olmAccount->maxOneTimeKeys()) // 2 // see note below + : signedKeysProportion(move(signedKeysProportion)), + oneTimeKeyThreshold(move(oneTimeKeyThreshold)) { Q_ASSERT((0 <= signedKeysProportion) && (signedKeysProportion <= 1)); Q_ASSERT((0 <= oneTimeKeyThreshold) && (oneTimeKeyThreshold <= 1)); + if (encryptionAccountPickle.isEmpty()) + { + olmAccount.reset(new Account()); + } else { + olmAccount.reset(new Account(encryptionAccountPickle)); // TODO: passphrase even with qtkeychain? + } /* * Note about targetKeysNumber: * @@ -42,17 +46,19 @@ class EncryptionManager::Private * used instantly, and we want them to stay in libolm, until the limit is reached * and it starts discarding keys, starting by the oldest. */ + targetKeysNumber = olmAccount->maxOneTimeKeys(); // 2 // see note below + targetOneTimeKeyCounts = + { + {SignedCurve25519Name, qRound(signedKeysProportion * targetKeysNumber)}, + {Curve25519Name, qRound((1-signedKeysProportion) * targetKeysNumber)} + }; } - ~Private() - { - delete olmAccount; - } + ~Private() = default; UploadKeysJob* uploadIdentityKeysJob = nullptr; UploadKeysJob* uploadOneTimeKeysJob = nullptr; - Account* olmAccount; - const QByteArray encryptionAccountPickle; + QScopedPointer<Account> olmAccount; float signedKeysProportion; float oneTimeKeyThreshold; @@ -68,11 +74,7 @@ class EncryptionManager::Private updateKeysToUpload(); } QHash<QString, int> oneTimeKeysToUploadCounts; - QHash<QString, int> targetOneTimeKeyCounts - { - {SignedCurve25519Name, qRound(signedKeysProportion * targetKeysNumber)}, - {Curve25519Name, qRound((1-signedKeysProportion) * targetKeysNumber)} - }; + QHash<QString, int> targetOneTimeKeyCounts; }; EncryptionManager::EncryptionManager(const QByteArray &encryptionAccountPickle, float signedKeysProportion, float oneTimeKeyThreshold, @@ -110,19 +112,29 @@ void EncryptionManager::uploadIdentityKeys(Connection* connection) d->olmAccount->ed25519IdentityKey() } }, - /* - * Signatures for the device key object. - * A map from user ID, to a map from <algorithm>:<device_id> to the signature. - * The signature is calculated using the process called Signing JSON. - */ + /* signatures should be provided after the unsigned deviceKeys generation */ + {} + }; + + QJsonObject deviceKeysJsonObject = toJson(deviceKeys); + /* additionally removing signatures key, + * since we could not initialize deviceKeys + * without an empty signatures value: + */ + deviceKeysJsonObject.remove(QStringLiteral("signatures")); + /* + * Signatures for the device key object. + * A map from user ID, to a map from <algorithm>:<device_id> to the signature. + * The signature is calculated using the process called Signing JSON. + */ + deviceKeys.signatures = + { { + connection->userId(), { - connection->userId(), { - { - ed25519Name + QStringLiteral(":") + connection->deviceId(), - d->olmAccount->sign(toJson(deviceKeys)) - } + ed25519Name + QStringLiteral(":") + connection->deviceId(), + d->olmAccount->sign(deviceKeysJsonObject) } } } @@ -183,6 +195,11 @@ void EncryptionManager::uploadOneTimeKeys(Connection* connection, bool forceUpda .arg(signedKeysToUploadCount).arg(unsignedKeysToUploadCount); } +QByteArray EncryptionManager::olmAccountPickle() +{ + return d->olmAccount->pickle(); // TODO: passphrase even with qtkeychain? +} + void EncryptionManager::Private::updateKeysToUpload() { for (auto it = targetOneTimeKeyCounts.cbegin(); it != targetOneTimeKeyCounts.cend(); ++it) diff --git a/lib/encryptionmanager.h b/lib/encryptionmanager.h index 0bd05432..40fe7383 100644 --- a/lib/encryptionmanager.h +++ b/lib/encryptionmanager.h @@ -15,12 +15,13 @@ namespace QMatrixClient public: // TODO: store constats separately? // TODO: 0.5 oneTimeKeyThreshold instead of 0.1? - explicit EncryptionManager(const QByteArray& encryptionAccountPickle, float signedKeysProportion = 1, float oneTimeKeyThreshold = float(0.1), + explicit EncryptionManager(const QByteArray& encryptionAccountPickle = QByteArray(), float signedKeysProportion = 1, float oneTimeKeyThreshold = float(0.1), QObject* parent = nullptr); ~EncryptionManager(); void uploadIdentityKeys(Connection* connection); void uploadOneTimeKeys(Connection* connection, bool forceUpdate = false); + QByteArray olmAccountPickle(); private: class Private; |