diff --git a/src/network/NetworkKey.cpp b/src/network/NetworkKey.cpp index 82b7fecb7d..e006d1a3a5 100644 --- a/src/network/NetworkKey.cpp +++ b/src/network/NetworkKey.cpp @@ -110,7 +110,7 @@ bool NetworkKey::LoadPrivate(SDL_RWops * file) } RSA * rsa; rsa = PEM_read_bio_RSAPrivateKey(bio, nullptr, nullptr, nullptr); - if (!RSA_check_key(rsa)) + if (rsa == nullptr || !RSA_check_key(rsa)) { log_error("Loaded RSA key is invalid"); BIO_free_all(bio); diff --git a/src/network/network.cpp b/src/network/network.cpp index 39165ae846..035b148b40 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -1875,14 +1875,27 @@ void Network::Client_Handle_TOKEN(NetworkConnection& connection, NetworkPacket& return; } SDL_RWops *privkey = SDL_RWFromFile(keyPath, "rb"); - key.LoadPrivate(privkey); + bool ok = key.LoadPrivate(privkey); + SDL_RWclose(privkey); + if (!ok) { + log_error("Failed to load key %s", keyPath); + connection.setLastDisconnectReason(STR_MULTIPLAYER_VERIFICATION_FAILURE); + shutdown(connection.socket, SHUT_RDWR); + return; + } uint32 challenge_size; packet >> challenge_size; const char *challenge = (const char *)packet.Read(challenge_size); size_t sigsize; char *signature; const std::string pubkey = key.PublicKeyString(); - bool ok = key.Sign(challenge, challenge_size, &signature, &sigsize); + ok = key.Sign(challenge, challenge_size, &signature, &sigsize); + if (!ok) { + log_error("Failed to sign server's challenge."); + connection.setLastDisconnectReason(STR_MULTIPLAYER_VERIFICATION_FAILURE); + shutdown(connection.socket, SHUT_RDWR); + return; + } // Don't keep private key in memory. There's no need and it may get leaked // when process dump gets collected at some point in future. key.Unload();