Saveload: Remove use of randombytes in company passwords storage

Use RandomBytesWithFallback
Replace related key/data arrays with std::array
pull/647/head
Jonathan G Rennison 4 months ago
parent 9492aa1c0d
commit f966153ae2

@ -71,8 +71,8 @@ bool _is_network_server; ///< Does this client wa
bool _network_settings_access; ///< Can this client change server settings?
NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies.
std::string _network_company_server_id; ///< Server ID string used for company passwords
uint8_t _network_company_password_storage_token[16]; ///< Non-secret token for storage of company passwords in savegames
uint8_t _network_company_password_storage_key[32]; ///< Key for storage of company passwords in savegames
std::array<uint8_t, 16> _network_company_password_storage_token; ///< Non-secret token for storage of company passwords in savegames
std::array<uint8_t, 32> _network_company_password_storage_key; ///< Key for storage of company passwords in savegames
ClientID _network_own_client_id; ///< Our client identifier.
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
uint8_t _network_reconnect; ///< Reconnect timeout

@ -26,8 +26,8 @@
extern NetworkCompanyState *_network_company_states;
extern std::string _network_company_server_id;
extern uint8_t _network_company_password_storage_token[16];
extern uint8_t _network_company_password_storage_key[32];
extern std::array<uint8_t, 16> _network_company_password_storage_token;
extern std::array<uint8_t, 32> _network_company_password_storage_key;
extern ClientID _network_own_client_id;
extern ClientID _redirect_console_to_client;

@ -1912,16 +1912,16 @@ static bool IsValidHex256BitKeyString(std::string &newval)
static void ParseCompanyPasswordStorageToken(const std::string &value)
{
extern uint8_t _network_company_password_storage_token[16];
extern std::array<uint8_t, 16> _network_company_password_storage_token;
if (value.size() != 32) return;
DecodeHexText(value.c_str(), _network_company_password_storage_token, 16);
DecodeHexText(value.c_str(), _network_company_password_storage_token.data(), _network_company_password_storage_token.size());
}
static void ParseCompanyPasswordStorageSecret(const std::string &value)
{
extern uint8_t _network_company_password_storage_key[32];
extern std::array<uint8_t, 32> _network_company_password_storage_key;
if (value.size() != 64) return;
DecodeHexText(value.c_str(), _network_company_password_storage_key, 32);
DecodeHexText(value.c_str(), _network_company_password_storage_key.data(), _network_company_password_storage_key.size());
}
/** Update the game info, and send it to the clients when we are running as a server. */

@ -20,7 +20,6 @@
#include "../network/network.h"
#include "../network/network_func.h"
#include "../network/network_server.h"
#include "../3rdparty/randombytes/randombytes.h"
#include "../3rdparty/monocypher/monocypher.h"
#include "saveload.h"
@ -592,23 +591,23 @@ static void Load_PLYP()
return;
}
uint8_t token[16];
ReadBuffer::GetCurrent()->CopyBytes(token, 16);
if (memcmp(token, _network_company_password_storage_token, 16) != 0) {
std::array<uint8_t, 16> token;
ReadBuffer::GetCurrent()->CopyBytes(token.data(), 16);
if (token != _network_company_password_storage_token) {
DEBUG(sl, 2, "Skipping encrypted company passwords");
SlSkipBytes(size - 16);
return;
}
uint8_t nonce[24];
uint8_t mac[16];
ReadBuffer::GetCurrent()->CopyBytes(nonce, 24);
ReadBuffer::GetCurrent()->CopyBytes(mac, 16);
std::array<uint8_t, 16> mac;
std::array<uint8_t, 24> nonce;
ReadBuffer::GetCurrent()->CopyBytes(nonce.data(), 24);
ReadBuffer::GetCurrent()->CopyBytes(mac.data(), 16);
std::vector<uint8_t> buffer(size - 16 - 24 - 16);
ReadBuffer::GetCurrent()->CopyBytes(buffer.data(), buffer.size());
if (crypto_aead_unlock(buffer.data(), mac, _network_company_password_storage_key, nonce, nullptr, 0, buffer.data(), buffer.size()) == 0) {
if (crypto_aead_unlock(buffer.data(), mac.data(), _network_company_password_storage_key.data(), nonce.data(), nullptr, 0, buffer.data(), buffer.size()) == 0) {
SlLoadFromBuffer(buffer.data(), buffer.size(), [invalid_mask]() {
_network_company_server_id.resize(SlReadUint32());
ReadBuffer::GetCurrent()->CopyBytes((uint8_t *)_network_company_server_id.data(), _network_company_server_id.size());
@ -652,13 +651,6 @@ static void Save_PLYP()
return;
}
uint8_t nonce[24]; /* Use only once per key: random */
if (randombytes(nonce, 24) < 0) {
/* Can't get a random nonce, just give up */
SlSetLength(0);
return;
}
std::vector<byte> buffer = SlSaveToVector([]() {
SlWriteUint32((uint32_t)_network_company_server_id.size());
MemoryDumper::GetCurrent()->CopyBytes((const uint8_t *)_network_company_server_id.data(), _network_company_server_id.size());
@ -674,27 +666,30 @@ static void Save_PLYP()
SlWriteUint16(0xFFFF);
/* Add some random length padding to not make it too obvious from the length whether passwords are set or not */
uint8_t padding[256];
if (randombytes(padding, 256) >= 0) {
SlWriteByte(padding[0]);
MemoryDumper::GetCurrent()->CopyBytes(padding + 1, padding[0]);
} else {
SlWriteByte(0);
}
std::array<uint8_t, 256> padding;
RandomBytesWithFallback(padding);
SlWriteByte(padding[0]);
MemoryDumper::GetCurrent()->CopyBytes(padding.data() + 1, padding[0]);
});
uint8_t mac[16]; /* Message authentication code */
/* Message authentication code */
std::array<uint8_t, 16> mac;
/* Use only once per key: random */
std::array<uint8_t, 24> nonce;
RandomBytesWithFallback(nonce);
/* Encrypt in place */
crypto_aead_lock(buffer.data(), mac, _network_company_password_storage_key, nonce, nullptr, 0, buffer.data(), buffer.size());
crypto_aead_lock(buffer.data(), mac.data(), _network_company_password_storage_key.data(), nonce.data(), nullptr, 0, buffer.data(), buffer.size());
SlSetLength(2 + 16 + 24 + 16 + buffer.size());
SlWriteUint16(0); // Invalid mask
MemoryDumper::GetCurrent()->CopyBytes(_network_company_password_storage_token, 16);
MemoryDumper::GetCurrent()->CopyBytes(nonce, 24);
MemoryDumper::GetCurrent()->CopyBytes(mac, 16);
MemoryDumper::GetCurrent()->CopyBytes(buffer.data(), buffer.size());
static_assert(_network_company_password_storage_token.size() == 16);
MemoryDumper::GetCurrent()->CopyBytes(_network_company_password_storage_token.data(), 16);
MemoryDumper::GetCurrent()->CopyBytes(nonce);
MemoryDumper::GetCurrent()->CopyBytes(mac);
MemoryDumper::GetCurrent()->CopyBytes(buffer);
}
static const ChunkHandler company_chunk_handlers[] = {

Loading…
Cancel
Save