mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
To debug RSA padding error
This commit is contained in:
parent
af293ec6dd
commit
54dd5da64c
4 changed files with 36 additions and 31 deletions
|
@ -285,7 +285,6 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) {
|
|||
packetReceiver.registerListener(PacketType::DomainConnectRequest, this, "processConnectRequestPacket");
|
||||
packetReceiver.registerListener(PacketType::DomainListRequest, this, "processListRequestPacket");
|
||||
packetReceiver.registerListener(PacketType::DomainServerPathQuery, this, "processPathQueryPacket");
|
||||
packetReceiver.registerListener(PacketType::DomainServerConnectionToken, this, "processConnectRequestPacket");
|
||||
packetReceiver.registerListener(PacketType::NodeJsonStats, this, "processNodeJSONStatsPacket");
|
||||
packetReceiver.registerListener(PacketType::ICEPing, this, "processICEPingPacket");
|
||||
packetReceiver.registerListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket");
|
||||
|
@ -578,6 +577,7 @@ const NodeSet STATICALLY_ASSIGNED_NODES = NodeSet() << NodeType::AudioMixer
|
|||
<< NodeType::AvatarMixer << NodeType::EntityServer;
|
||||
|
||||
void DomainServer::processConnectRequestPacket(QSharedPointer<NLPacket> packet) {
|
||||
|
||||
NodeType_t nodeType;
|
||||
HifiSockAddr publicSockAddr, localSockAddr;
|
||||
|
||||
|
@ -638,23 +638,22 @@ void DomainServer::processConnectRequestPacket(QSharedPointer<NLPacket> packet)
|
|||
if (packet->bytesLeftToRead() > 0) {
|
||||
// try to verify username and usernameSignature
|
||||
packetStream >> username >> usernameSignature;
|
||||
} else {
|
||||
|
||||
QUuid connectionToken = _connectionTokenHash[username];
|
||||
} else {
|
||||
// if user didn't include username and usernameSignature in connect request, send a connectionToken packet
|
||||
QUuid& connectionToken = _connectionTokenHash[username];
|
||||
|
||||
if(connectionToken.isNull()) {
|
||||
// set up the connection token packet
|
||||
static auto connectionTokenPacket = NLPacket::create(PacketType::DomainServerConnectionToken, NUM_BYTES_RFC4122_UUID);
|
||||
connectionTokenPacket.reset();
|
||||
connectionTokenPacket->write(connectionToken.toRfc4122());
|
||||
nodeList->sendUnreliablePacket(connectionToken, packet->getSenderSockAddr());
|
||||
return;
|
||||
} else {
|
||||
// reset existing packet
|
||||
|
||||
//connectionTokenPacket.reset();
|
||||
connectionToken = QUuid::createUuid();
|
||||
}
|
||||
|
||||
static auto connectionTokenPacket = NLPacket::create(PacketType::DomainServerConnectionToken, NUM_BYTES_RFC4122_UUID);
|
||||
connectionTokenPacket->reset();
|
||||
connectionTokenPacket->write(connectionToken.toRfc4122());
|
||||
limitedNodeList->sendUnreliablePacket(*connectionTokenPacket, packet->getSenderSockAddr());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
QString reason;
|
||||
|
@ -793,9 +792,8 @@ bool DomainServer::verifyUserSignature(const QString& username,
|
|||
const QByteArray& usernameSignature,
|
||||
QString& reasonReturn) {
|
||||
// it's possible this user can be allowed to connect, but we need to check their username signature
|
||||
|
||||
|
||||
QByteArray publicKeyArray = _userPublicKeys.value(username);
|
||||
QUuid connectionToken = _connectionTokenHash.value(username);
|
||||
if (!publicKeyArray.isEmpty()) {
|
||||
// if we do have a public key for the user, check for a signature match
|
||||
|
||||
|
@ -803,7 +801,8 @@ bool DomainServer::verifyUserSignature(const QString& username,
|
|||
|
||||
// first load up the public key into an RSA struct
|
||||
RSA* rsaPublicKey = d2i_RSA_PUBKEY(NULL, &publicKeyData, publicKeyArray.size());
|
||||
|
||||
|
||||
|
||||
if (rsaPublicKey) {
|
||||
QByteArray decryptedArray(RSA_size(rsaPublicKey), 0);
|
||||
int decryptResult =
|
||||
|
@ -813,10 +812,13 @@ bool DomainServer::verifyUserSignature(const QString& username,
|
|||
rsaPublicKey, RSA_PKCS1_PADDING);
|
||||
|
||||
QByteArray lowercaseUsername = username.toLower().toUtf8();
|
||||
QUuid connectionToken = _connectionTokenHash[username];
|
||||
QByteArray usernameWithToken = lowercaseUsername.append(connectionToken.toRfc4122());
|
||||
QByteArray usernameWithToken = QCryptographicHash::hash(lowercaseUsername.append(connectionToken.toRfc4122()), QCryptographicHash::Sha256);
|
||||
|
||||
int err = ERR_get_error();
|
||||
qDebug() << "Error: " << err;
|
||||
|
||||
if (decryptResult != -1) {
|
||||
|
||||
if (usernameWithToken == decryptedArray) {
|
||||
qDebug() << "Username signature matches for" << username << "- allowing connection.";
|
||||
|
||||
|
@ -834,10 +836,13 @@ bool DomainServer::verifyUserSignature(const QString& username,
|
|||
} else {
|
||||
qDebug() << "Couldn't decrypt user signature for" << username << "- denying connection.";
|
||||
reasonReturn = "Couldn't decrypt user signature.";
|
||||
|
||||
}
|
||||
|
||||
// free up the public key, we don't need it anymore
|
||||
RSA_free(rsaPublicKey);
|
||||
_connectionTokenHash.remove(username);
|
||||
|
||||
} else {
|
||||
// we can't let this user in since we couldn't convert their public key to an RSA key we could use
|
||||
qDebug() << "Couldn't convert data to RSA key for" << username << "- denying connection.";
|
||||
|
@ -859,10 +864,10 @@ bool DomainServer::shouldAllowConnectionFromNode(const QString& username,
|
|||
_settingsManager.valueOrDefaultValueForKeyPath(RESTRICTED_ACCESS_SETTINGS_KEYPATH).toBool();
|
||||
|
||||
// we always let in a user who is sending a packet from our local socket or from the localhost address
|
||||
if (senderSockAddr.getAddress() == DependencyManager::get<LimitedNodeList>()->getLocalSockAddr().getAddress()
|
||||
|| senderSockAddr.getAddress() == QHostAddress::LocalHost) {
|
||||
return true;
|
||||
}
|
||||
// if (senderSockAddr.getAddress() == DependencyManager::get<LimitedNodeList>()->getLocalSockAddr().getAddress()
|
||||
// || senderSockAddr.getAddress() == QHostAddress::LocalHost) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (isRestrictingAccess) {
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ void DataServerAccountInfo::setProfileInfoFromJSON(const QJsonObject& jsonObject
|
|||
}
|
||||
|
||||
QByteArray DataServerAccountInfo::getUsernameSignature(const QUuid& connectionToken) {
|
||||
|
||||
if (!_privateKey.isEmpty()) {
|
||||
const char* privateKeyData = _privateKey.constData();
|
||||
RSA* rsaPrivateKey = d2i_RSAPrivateKey(NULL,
|
||||
|
@ -136,16 +137,14 @@ QByteArray DataServerAccountInfo::getUsernameSignature(const QUuid& connectionTo
|
|||
_privateKey.size());
|
||||
if (rsaPrivateKey) {
|
||||
QByteArray lowercaseUsername = _username.toLower().toUtf8();
|
||||
QByteArray usernameWithToken = lowercaseUsername.append(connectionToken.toRfc4122());
|
||||
|
||||
QByteArray usernameWithToken = QCryptographicHash::hash(lowercaseUsername.append(connectionToken.toRfc4122()), QCryptographicHash::Sha256);
|
||||
QByteArray usernameSignature(RSA_size(rsaPrivateKey), 0);
|
||||
|
||||
int encryptReturn = RSA_private_encrypt(lowercaseUsername.size(),
|
||||
int encryptReturn = RSA_private_encrypt(usernameWithToken.size(),
|
||||
reinterpret_cast<const unsigned char*>(usernameWithToken.constData()),
|
||||
reinterpret_cast<unsigned char*>(usernameSignature.data()),
|
||||
rsaPrivateKey, RSA_PKCS1_PADDING);
|
||||
|
||||
|
||||
|
||||
// free the private key RSA struct now that we are done with it
|
||||
RSA_free(rsaPrivateKey);
|
||||
|
@ -154,6 +153,7 @@ QByteArray DataServerAccountInfo::getUsernameSignature(const QUuid& connectionTo
|
|||
qCDebug(networking) << "Error encrypting username signature.";
|
||||
qCDebug(networking) << "Will re-attempt on next domain-server check in.";
|
||||
} else {
|
||||
qDebug(networking) << "Signing username with connectionUUID";
|
||||
return usernameSignature;
|
||||
}
|
||||
|
||||
|
|
|
@ -277,19 +277,20 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
|
||||
// if this is a connect request, and we can present a username signature, send it along
|
||||
if (!_domainHandler.isConnected() ) {
|
||||
|
||||
DataServerAccountInfo& accountInfo = AccountManager::getInstance().getAccountInfo();
|
||||
packetStream << accountInfo.getUsername();
|
||||
|
||||
// get connection token from the domain-server
|
||||
const QUuid& connectionToken = _domainHandler.getConnectionToken();
|
||||
|
||||
if(!connectionToken.isNull()) {
|
||||
|
||||
const QByteArray& usernameSignature = AccountManager::getInstance().getAccountInfo().getUsernameSignature(connectionToken);
|
||||
|
||||
if (!usernameSignature.isEmpty()) {
|
||||
qCDebug(networking) << "Including username signature in domain connect request.";
|
||||
packetStream << usernameSignature;
|
||||
packetStream << accountInfo.getUsername() << usernameSignature;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,7 +463,6 @@ void NodeList::processDomainServerConnectionTokenPacket(QSharedPointer<NLPacket>
|
|||
// refuse to process this packet if we aren't currently connected to the DS
|
||||
return;
|
||||
}
|
||||
|
||||
// read in the connection token from the packet, then send domain-server checkin
|
||||
_domainHandler.setConnectionToken(QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)));
|
||||
sendDomainServerCheckIn();
|
||||
|
|
|
@ -26,8 +26,8 @@ const QSet<PacketType::Value> SEQUENCE_NUMBERED_PACKETS = QSet<PacketType::Value
|
|||
|
||||
const QSet<PacketType::Value> NON_SOURCED_PACKETS = QSet<PacketType::Value>()
|
||||
<< StunResponse << CreateAssignment << RequestAssignment
|
||||
<< DomainServerRequireDTLS << DomainConnectRequest
|
||||
<< DomainList << DomainConnectionDenied << DomainServerConnectionToken
|
||||
<< DomainServerRequireDTLS << DomainConnectRequest << DomainServerConnectionToken
|
||||
<< DomainList << DomainConnectionDenied
|
||||
<< DomainServerPathQuery << DomainServerPathResponse
|
||||
<< DomainServerAddedNode
|
||||
<< ICEServerPeerInformation << ICEServerQuery << ICEServerHeartbeat
|
||||
|
|
Loading…
Reference in a new issue