| 1506 | |
| 1507 | |
| 1508 | void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) |
| 1509 | { |
| 1510 | short EncKeyLength, EncNonceLength; |
| 1511 | a_ByteBuffer.ReadBEShort(EncKeyLength); |
| 1512 | AString EncKey; |
| 1513 | if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength)) |
| 1514 | { |
| 1515 | return; |
| 1516 | } |
| 1517 | a_ByteBuffer.ReadBEShort(EncNonceLength); |
| 1518 | AString EncNonce; |
| 1519 | if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength)) |
| 1520 | { |
| 1521 | return; |
| 1522 | } |
| 1523 | if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN)) |
| 1524 | { |
| 1525 | LOGD("Too long encryption"); |
| 1526 | m_Client->Kick("Hacked client"); |
| 1527 | return; |
| 1528 | } |
| 1529 | |
| 1530 | // Decrypt EncNonce using privkey |
| 1531 | cRSAPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey(); |
| 1532 | Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)]; |
| 1533 | int res = rsaDecryptor.Decrypt((const Byte *)EncNonce.data(), EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce)); |
| 1534 | if (res != 4) |
| 1535 | { |
| 1536 | LOGD("Bad nonce length: got %d, exp %d", res, 4); |
| 1537 | m_Client->Kick("Hacked client"); |
| 1538 | return; |
| 1539 | } |
| 1540 | if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this) |
| 1541 | { |
| 1542 | LOGD("Bad nonce value"); |
| 1543 | m_Client->Kick("Hacked client"); |
| 1544 | return; |
| 1545 | } |
| 1546 | |
| 1547 | // Decrypt the symmetric encryption key using privkey: |
| 1548 | Byte DecryptedKey[MAX_ENC_LEN]; |
| 1549 | res = rsaDecryptor.Decrypt((const Byte *)EncKey.data(), EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); |
| 1550 | if (res != 16) |
| 1551 | { |
| 1552 | LOGD("Bad key length"); |
| 1553 | m_Client->Kick("Hacked client"); |
| 1554 | return; |
| 1555 | } |
| 1556 | |
| 1557 | StartEncryption(DecryptedKey); |
| 1558 | |
| 1559 | // Send login success: |
| 1560 | { |
| 1561 | cPacketizer Pkt(*this, 0x02); // Login success packet |
| 1562 | Pkt.WriteString(Printf("%d", m_Client->GetUniqueID())); // TODO: proper UUID |
| 1563 | Pkt.WriteString(m_Client->GetUsername()); |
| 1564 | } |
| 1565 |
nothing calls this directly
no test coverage detected