Merge pull request #15912 from SimonWalton-HiFi/early-rsa-keygen

BUGZ-918: Generate RSA key-pair early in start-up
This commit is contained in:
Shannon Romano 2019-07-12 09:42:11 -07:00 committed by GitHub
commit 74b830dd12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 11 deletions

View file

@ -1187,6 +1187,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
} }
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
// set the account manager's root URL and trigger a login request if we don't have the access token
accountManager->setIsAgent(true);
accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());
if (!accountManager->hasKeyPair()) {
accountManager->generateNewUserKeypair();
}
#ifndef Q_OS_ANDROID #ifndef Q_OS_ANDROID
_logger->setSessionID(accountManager->getSessionID()); _logger->setSessionID(accountManager->getSessionID());
#endif #endif
@ -1334,10 +1341,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
#endif #endif
connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle); connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
// set the account manager's root URL and trigger a login request if we don't have the access token
accountManager->setIsAgent(true);
accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());
// use our MyAvatar position and quat for address manager path // use our MyAvatar position and quat for address manager path
addressManager->setPositionGetter([] { addressManager->setPositionGetter([] {
auto avatarManager = DependencyManager::get<AvatarManager>(); auto avatarManager = DependencyManager::get<AvatarManager>();

View file

@ -86,6 +86,7 @@ AccountManager::AccountManager(UserAgentGetter userAgentGetter) :
qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*"); qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*");
qRegisterMetaType<AccountManagerAuth::Type>(); qRegisterMetaType<AccountManagerAuth::Type>();
connect(this, &AccountManager::loginComplete, this, &AccountManager::uploadPublicKey);
} }
const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash"; const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash";
@ -838,18 +839,30 @@ void AccountManager::generateNewKeypair(bool isUserKeypair, const QUuid& domainI
connect(keypairGenerator, &RSAKeypairGenerator::errorGeneratingKeypair, this, connect(keypairGenerator, &RSAKeypairGenerator::errorGeneratingKeypair, this,
&AccountManager::handleKeypairGenerationError); &AccountManager::handleKeypairGenerationError);
qCDebug(networking) << "Starting worker thread to generate 2048-bit RSA keypair."; static constexpr int RSA_THREAD_PRIORITY = 1;
qCDebug(networking) << "Starting worker thread to generate 2048-bit RSA keypair, priority"
<< RSA_THREAD_PRIORITY << "- QThreadPool::maxThreadCount =" << QThreadPool::globalInstance()->maxThreadCount();
// Start on Qt's global thread pool. // Start on Qt's global thread pool.
QThreadPool::globalInstance()->start(keypairGenerator); QThreadPool::globalInstance()->start(keypairGenerator, RSA_THREAD_PRIORITY);
} }
} }
void AccountManager::processGeneratedKeypair(QByteArray publicKey, QByteArray privateKey) { void AccountManager::processGeneratedKeypair(QByteArray publicKey, QByteArray privateKey) {
qCDebug(networking) << "Generated 2048-bit RSA keypair. Uploading public key now."; qCDebug(networking) << "Generated 2048-bit RSA keypair.";
// hold the private key to later set our metaverse API account info if upload succeeds // hold the private key to later set our metaverse API account info if upload succeeds
_pendingPublicKey = publicKey;
_pendingPrivateKey = privateKey; _pendingPrivateKey = privateKey;
uploadPublicKey();
}
void AccountManager::uploadPublicKey() {
if (_pendingPrivateKey.isEmpty()) {
return;
}
qCDebug(networking) << "Attempting upload of public key";
// upload the public key so data-web has an up-to-date key // upload the public key so data-web has an up-to-date key
const QString USER_PUBLIC_KEY_UPDATE_PATH = "api/v1/user/public_key"; const QString USER_PUBLIC_KEY_UPDATE_PATH = "api/v1/user/public_key";
@ -871,7 +884,7 @@ void AccountManager::processGeneratedKeypair(QByteArray publicKey, QByteArray pr
publicKeyPart.setHeader(QNetworkRequest::ContentDispositionHeader, publicKeyPart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"public_key\"; filename=\"public_key\"")); QVariant("form-data; name=\"public_key\"; filename=\"public_key\""));
publicKeyPart.setBody(publicKey); publicKeyPart.setBody(_pendingPublicKey);
requestMultiPart->append(publicKeyPart); requestMultiPart->append(publicKeyPart);
// Currently broken? We don't have the temporary domain key. // Currently broken? We don't have the temporary domain key.
@ -900,6 +913,7 @@ void AccountManager::publicKeyUploadSucceeded(QNetworkReply* reply) {
// public key upload complete - store the matching private key and persist the account to settings // public key upload complete - store the matching private key and persist the account to settings
_accountInfo.setPrivateKey(_pendingPrivateKey); _accountInfo.setPrivateKey(_pendingPrivateKey);
_pendingPublicKey.clear();
_pendingPrivateKey.clear(); _pendingPrivateKey.clear();
persistAccountToFile(); persistAccountToFile();
@ -915,9 +929,6 @@ void AccountManager::publicKeyUploadFailed(QNetworkReply* reply) {
// we aren't waiting for a response any longer // we aren't waiting for a response any longer
_isWaitingForKeypairResponse = false; _isWaitingForKeypairResponse = false;
// clear our pending private key
_pendingPrivateKey.clear();
} }
void AccountManager::handleKeypairGenerationError() { void AccountManager::handleKeypairGenerationError() {
@ -961,3 +972,7 @@ void AccountManager::saveLoginStatus(bool isLoggedIn) {
} }
} }
} }
bool AccountManager::hasKeyPair() const {
return _accountInfo.hasPrivateKey();
}

View file

@ -81,6 +81,7 @@ public:
bool needsToRefreshToken(); bool needsToRefreshToken();
Q_INVOKABLE bool checkAndSignalForAccessToken(); Q_INVOKABLE bool checkAndSignalForAccessToken();
void setAccessTokenForCurrentAuthURL(const QString& accessToken); void setAccessTokenForCurrentAuthURL(const QString& accessToken);
bool hasKeyPair() const;
void requestProfile(); void requestProfile();
@ -139,6 +140,7 @@ signals:
private slots: private slots:
void handleKeypairGenerationError(); void handleKeypairGenerationError();
void processGeneratedKeypair(QByteArray publicKey, QByteArray privateKey); void processGeneratedKeypair(QByteArray publicKey, QByteArray privateKey);
void uploadPublicKey();
void publicKeyUploadSucceeded(QNetworkReply* reply); void publicKeyUploadSucceeded(QNetworkReply* reply);
void publicKeyUploadFailed(QNetworkReply* reply); void publicKeyUploadFailed(QNetworkReply* reply);
void generateNewKeypair(bool isUserKeypair = true, const QUuid& domainID = QUuid()); void generateNewKeypair(bool isUserKeypair = true, const QUuid& domainID = QUuid());
@ -162,6 +164,7 @@ private:
bool _isWaitingForKeypairResponse { false }; bool _isWaitingForKeypairResponse { false };
QByteArray _pendingPrivateKey; QByteArray _pendingPrivateKey;
QByteArray _pendingPublicKey;
QUuid _sessionID { QUuid::createUuid() }; QUuid _sessionID { QUuid::createUuid() };