have DSAI generate a username signature upon request, when it has private key

This commit is contained in:
Stephen Birarda 2014-10-14 15:15:16 -07:00
parent 22b599b8cc
commit 970f2c7fad
4 changed files with 58 additions and 7 deletions

View file

@ -70,7 +70,7 @@ public:
void requestAccessToken(const QString& login, const QString& password);
void requestProfile();
const DataServerAccountInfo& getAccountInfo() const { return _accountInfo; }
DataServerAccountInfo& getAccountInfo() { return _accountInfo; }
public slots:
void requestAccessTokenFinished();

View file

@ -9,6 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <openssl/rsa.h>
#include <QtCore/QDebug>
#include "DataServerAccountInfo.h"
@ -21,7 +23,8 @@ DataServerAccountInfo::DataServerAccountInfo() :
_walletID(),
_balance(0),
_hasBalance(false),
_privateKey()
_privateKey(),
_usernameSignature()
{
}
@ -64,6 +67,9 @@ void DataServerAccountInfo::setUsername(const QString& username) {
if (_username != username) {
_username = username;
// clear our username signature so it has to be re-created
_usernameSignature = QByteArray();
qDebug() << "Username changed to" << username;
}
}
@ -114,6 +120,49 @@ void DataServerAccountInfo::setProfileInfoFromJSON(const QJsonObject& jsonObject
setWalletID(QUuid(user["wallet_id"].toString()));
}
const QByteArray& DataServerAccountInfo::usernameSignature() {
if (_usernameSignature.isEmpty()) {
if (!_privateKey.isEmpty()) {
const char* privateKeyData = _privateKey.constData();
RSA* rsaPrivateKey = d2i_RSAPrivateKey(NULL,
reinterpret_cast<const unsigned char**>(&privateKeyData),
_privateKey.size());
if (rsaPrivateKey) {
QByteArray usernameByteArray = _username.toUtf8();
QByteArray encryptedUsername(RSA_size(rsaPrivateKey), 0);
int encryptReturn = RSA_private_encrypt(usernameByteArray.size(),
reinterpret_cast<const unsigned char*>(usernameByteArray.constData()),
reinterpret_cast<unsigned char*>(encryptedUsername.data()),
rsaPrivateKey, RSA_PKCS1_PADDING);
if (encryptReturn != -1) {
_usernameSignature = usernameByteArray;
_usernameSignature.append(encryptedUsername);
} else {
qDebug() << "Error encrypting username signature.";
qDebug() << "Will re-attempt on next domain-server check in.";
}
} else {
qDebug() << "Could not create RSA struct from QByteArray private key.";
qDebug() << "Will re-attempt on next domain-server check in.";
}
} else {
qDebug() << "No private key present in DataServerAccountInfo. Re-log to generate new key.";
qDebug() << "Returning empty username signature.";
}
}
return _usernameSignature;
}
void DataServerAccountInfo::setPrivateKey(const QByteArray& privateKey) {
_privateKey = privateKey;
// clear our username signature so it has to be re-created
_usernameSignature = QByteArray();
}
QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info) {
out << info._accessToken << info._username << info._xmppPassword << info._discourseApiKey
<< info._walletID << info._privateKey;

View file

@ -42,8 +42,8 @@ public:
const QUuid& getWalletID() const { return _walletID; }
void setWalletID(const QUuid& walletID);
const QByteArray& getPrivateKey() const { return _privateKey; }
void setPrivateKey(const QByteArray& privateKey) { _privateKey = privateKey; }
const QByteArray& usernameSignature();
void setPrivateKey(const QByteArray& privateKey);
qint64 getBalance() const { return _balance; }
float getBalanceInSatoshis() const { return _balance / SATOSHIS_PER_CREDIT; }
@ -71,6 +71,7 @@ private:
qint64 _balance;
bool _hasBalance;
QByteArray _privateKey;
QByteArray _usernameSignature;
};
#endif // hifi_DataServerAccountInfo_h

View file

@ -310,11 +310,12 @@ void NodeList::sendDomainServerCheckIn() {
}
// if this is a connect request, and we can present a username signature, send it along
AccountManager& accountManager = AccountManager::getInstance();
const QByteArray& privateKey = accountManager.getAccountInfo().getPrivateKey();
if (!_domainHandler.isConnected()) {
if (!privateKey.isEmpty()) {
const QByteArray& usernameSignature = AccountManager::getInstance().getAccountInfo().usernameSignature();
if (!usernameSignature.isEmpty()) {
qDebug() << "Including username signature in domain connect request.";
packetStream << usernameSignature;
} else {
qDebug() << "Private key not present - domain connect request cannot include username signature";
}