From 62eb761946b285165a357cfcfff8814afd5392df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Mon, 6 Jul 2020 11:35:40 -0400
Subject: [PATCH] account manager: set private key on first load

Change-Id: If047cc1e32a5cb04c5b6a5341c416be6db3ee7e4
---
 src/jamidht/account_manager.cpp         | 14 ++++++++++++++
 src/jamidht/account_manager.h           |  5 ++++-
 src/jamidht/archive_account_manager.cpp |  6 ++++--
 src/jamidht/archive_account_manager.h   |  3 ++-
 src/jamidht/jamiaccount.cpp             | 11 +----------
 src/jamidht/server_account_manager.cpp  |  6 ++++--
 src/jamidht/server_account_manager.h    |  3 ++-
 7 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/src/jamidht/account_manager.cpp b/src/jamidht/account_manager.cpp
index 010ac1859f..61e8e0278a 100644
--- a/src/jamidht/account_manager.cpp
+++ b/src/jamidht/account_manager.cpp
@@ -26,6 +26,7 @@
 #include "libdevcrypto/Common.h"
 
 #include <opendht/thread_pool.h>
+#include <opendht/crypto.h>
 
 #include <exception>
 #include <future>
@@ -33,6 +34,19 @@
 
 namespace jami {
 
+AccountManager::CertRequest
+AccountManager::buildRequest(PrivateKey fDeviceKey)
+{
+    return dht::ThreadPool::computation().get<std::unique_ptr<dht::crypto::CertificateRequest>>([fDeviceKey]{
+        auto request = std::make_unique<dht::crypto::CertificateRequest>();
+        request->setName("Jami device");
+        auto deviceKey = fDeviceKey.get();
+        request->setUID(deviceKey->getPublicKey().getId().toString());
+        request->sign(*deviceKey);
+        return request;
+    });
+}
+
 dht::crypto::Identity
 AccountManager::loadIdentity(const std::string& crt_path, const std::string& key_path, const std::string& key_pwd) const
 {
diff --git a/src/jamidht/account_manager.h b/src/jamidht/account_manager.h
index 4aa1e1822d..4ce18ade1c 100644
--- a/src/jamidht/account_manager.h
+++ b/src/jamidht/account_manager.h
@@ -101,6 +101,9 @@ public:
     using AuthFailureCallback = std::function<void(AuthError error, const std::string& message)>;
     using DeviceSyncCallback = std::function<void(DeviceSync&& syncData)>;
     using CertRequest = std::future<std::unique_ptr<dht::crypto::CertificateRequest>>;
+    using PrivateKey = std::shared_future<std::shared_ptr<dht::crypto::PrivateKey>>;
+
+    CertRequest buildRequest(PrivateKey fDeviceKey);
 
     struct AccountCredentials {
         std::string scheme;
@@ -110,7 +113,7 @@ public:
     };
 
     virtual void initAuthentication(
-        CertRequest request,
+        PrivateKey request,
         std::string deviceName,
         std::unique_ptr<AccountCredentials> credentials,
         AuthSuccessCallback onSuccess,
diff --git a/src/jamidht/archive_account_manager.cpp b/src/jamidht/archive_account_manager.cpp
index c5f1202773..7fb81a4731 100644
--- a/src/jamidht/archive_account_manager.cpp
+++ b/src/jamidht/archive_account_manager.cpp
@@ -36,7 +36,7 @@ const constexpr auto EXPORT_KEY_RENEWAL_TIME = std::chrono::minutes(20);
 
 void
 ArchiveAccountManager::initAuthentication(
-    CertRequest request,
+    PrivateKey key,
     std::string deviceName,
     std::unique_ptr<AccountCredentials> credentials,
     AuthSuccessCallback onSuccess,
@@ -44,7 +44,8 @@ ArchiveAccountManager::initAuthentication(
     OnChangeCallback onChange)
 {
     auto ctx = std::make_shared<AuthContext>();
-    ctx->request = std::move(request);
+    ctx->key = key;
+    ctx->request = buildRequest(key);
     ctx->deviceName = std::move(deviceName);
     ctx->credentials = dynamic_unique_cast<ArchiveAccountCredentials>(std::move(credentials));
     ctx->onSuccess = std::move(onSuccess);
@@ -324,6 +325,7 @@ ArchiveAccountManager::onArchiveLoaded(
     auto receiptSignature = a.id.first->sign({receipt.first.begin(), receipt.first.end()});
 
     auto info = std::make_unique<AccountInfo>();
+    info->identity.first = ctx.key.get();
     info->identity.second = deviceCertificate;
     info->accountId = a.id.second->getId().toString();
     info->deviceId = deviceCertificate->getPublicKey().getId().toString();
diff --git a/src/jamidht/archive_account_manager.h b/src/jamidht/archive_account_manager.h
index ef7778aa1c..55b5ef063c 100644
--- a/src/jamidht/archive_account_manager.h
+++ b/src/jamidht/archive_account_manager.h
@@ -43,7 +43,7 @@ public:
     };
 
     void initAuthentication(
-        CertRequest request,
+        PrivateKey request,
         std::string deviceName,
         std::unique_ptr<AccountCredentials> credentials,
         AuthSuccessCallback onSuccess,
@@ -71,6 +71,7 @@ public:
 private:
     struct DhtLoadContext;
     struct AuthContext {
+        PrivateKey key;
         CertRequest request;
         std::string deviceName;
         std::unique_ptr<ArchiveAccountCredentials> credentials;
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index 080d979acb..b92bceac4b 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -1118,15 +1118,6 @@ JamiAccount::loadAccount(const std::string& archive_password, const std::string&
                 return std::make_shared<dht::crypto::PrivateKey>(dht::crypto::PrivateKey::generate());
             });
 
-            auto fReq = dht::ThreadPool::computation().get<std::unique_ptr<dht::crypto::CertificateRequest>>([fDeviceKey]{
-                auto request = std::make_unique<dht::crypto::CertificateRequest>();
-                request->setName("Jami device");
-                auto deviceKey = fDeviceKey.get();
-                request->setUID(deviceKey->getPublicKey().getId().toString());
-                request->sign(*deviceKey);
-                return request;
-            });
-
             std::unique_ptr<AccountManager::AccountCredentials> creds;
             if (managerUri_.empty()) {
                 auto acreds = std::make_unique<ArchiveAccountManager::ArchiveAccountCredentials>();
@@ -1164,7 +1155,7 @@ JamiAccount::loadAccount(const std::string& archive_password, const std::string&
             bool isManaged = !managerUri_.empty();
 
             accountManager_->initAuthentication(
-                std::move(fReq),
+                fDeviceKey,
                 ip_utils::getDeviceName(),
                 std::move(creds),
                 [this, fDeviceKey, migrating](const AccountInfo& info,
diff --git a/src/jamidht/server_account_manager.cpp b/src/jamidht/server_account_manager.cpp
index cc913fbc52..688db1677a 100644
--- a/src/jamidht/server_account_manager.cpp
+++ b/src/jamidht/server_account_manager.cpp
@@ -58,7 +58,7 @@ ServerAccountManager::setAuthHeaderFields(Request& request) const {
 
 void
 ServerAccountManager::initAuthentication(
-    CertRequest csrRequest,
+    PrivateKey key,
     std::string deviceName,
     std::unique_ptr<AccountCredentials> credentials,
     AuthSuccessCallback onSuccess,
@@ -66,7 +66,8 @@ ServerAccountManager::initAuthentication(
     OnChangeCallback onChange)
 {
     auto ctx = std::make_shared<AuthContext>();
-    ctx->request = std::move(csrRequest);
+    ctx->key = key;
+    ctx->request = buildRequest(key);
     ctx->deviceName = std::move(deviceName);
     ctx->credentials = dynamic_unique_cast<ServerAccountCredentials>(std::move(credentials));
     ctx->onSuccess = std::move(onSuccess);
@@ -125,6 +126,7 @@ ServerAccountManager::initAuthentication(
                                 auto receiptSignature = base64::decode(json["receiptSignature"].asString());
 
                                 auto info = std::make_unique<AccountInfo>();
+                                info->identity.first = ctx->key.get();
                                 info->identity.second = cert;
                                 info->deviceId = cert->getPublicKey().getId().toString();
                                 info->accountId = accountCert->getId().toString();
diff --git a/src/jamidht/server_account_manager.h b/src/jamidht/server_account_manager.h
index f510cf4b15..6b33cb41ab 100644
--- a/src/jamidht/server_account_manager.h
+++ b/src/jamidht/server_account_manager.h
@@ -39,7 +39,7 @@ public:
     };
 
     void initAuthentication(
-        CertRequest request,
+        PrivateKey request,
         std::string deviceName,
         std::unique_ptr<AccountCredentials> credentials,
         AuthSuccessCallback onSuccess,
@@ -59,6 +59,7 @@ public:
 
 private:
     struct AuthContext {
+        PrivateKey key;
         CertRequest request;
         std::string deviceName;
         std::unique_ptr<ServerAccountCredentials> credentials;
-- 
GitLab