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