aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connection.cpp3
-rw-r--r--lib/encryptionmanager.cpp67
-rw-r--r--lib/encryptionmanager.h3
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;