OpenTTD Source
20240917-master-g9ab0a47812
|
Go to the documentation of this file.
10 #include "../stdafx.h"
15 #include "../3rdparty/monocypher/monocypher.h"
16 #include "../core/random_func.hpp"
18 #include "../string_func.h"
20 #include "../safeguards.h"
68 crypto_x25519(shared_secret.data(), our_secret_key.data(), peer_public_key.data());
69 if (std::all_of(shared_secret.begin(), shared_secret.end(), [](
auto v) { return v == 0; })) {
74 crypto_blake2b_ctx ctx;
75 crypto_blake2b_init(&ctx, this->
keys.size());
76 crypto_blake2b_update(&ctx, shared_secret.data(), shared_secret.size());
79 crypto_blake2b_update(&ctx, our_public_key.data(), our_public_key.size());
80 crypto_blake2b_update(&ctx, peer_public_key.data(), peer_public_key.size());
83 crypto_blake2b_update(&ctx, peer_public_key.data(), peer_public_key.size());
84 crypto_blake2b_update(&ctx, our_public_key.data(), our_public_key.size());
89 crypto_blake2b_update(&ctx,
reinterpret_cast<const uint8_t *
>(extra_payload.data()), extra_payload.size());
90 crypto_blake2b_final(&ctx, this->
keys.data());
110 crypto_aead_init_x(&this->context, key.data(), nonce.data());
116 crypto_wipe(&this->context,
sizeof(this->context));
124 bool Decrypt(std::span<std::uint8_t> mac, std::span<std::uint8_t> message)
override
126 return crypto_aead_read(&this->context, message.data(), mac.data(),
nullptr, 0, message.data(), message.size()) == 0;
129 void Encrypt(std::span<std::uint8_t> mac, std::span<std::uint8_t> message)
override
131 crypto_aead_write(&this->context, message.data(), mac.data(),
nullptr, 0, message.data(), message.size());
159 crypto_x25519_public_key(public_key.data(), this->data());
185 our_secret_key(secret_key), our_public_key(secret_key.CreatePublicKey()),
190 void X25519AuthenticationHandler::SendRequest(
Packet &p)
204 Debug(net, 1,
"[crypto] Received auth response of illegal size; authentication aborted.");
222 this->our_secret_key, this->our_public_key, derived_key_extra_payload)) {
223 Debug(net, 0,
"[crypto] Peer sent an illegal public key; authentication aborted.");
231 crypto_aead_lock(message.data(), mac.data(), this->derived_keys.ClientToServer().data(), this->key_exchange_nonce.data(),
232 this->our_public_key.data(), this->our_public_key.size(), message.data(), message.size());
268 std::unique_ptr<NetworkEncryptionHandler> X25519AuthenticationHandler::CreateClientToServerEncryptionHandler()
const
273 std::unique_ptr<NetworkEncryptionHandler> X25519AuthenticationHandler::CreateServerToClientEncryptionHandler()
const
288 Debug(net, 1,
"[crypto] Received auth response of illegal size; authentication aborted.");
300 this->our_secret_key, this->our_public_key, derived_key_extra_payload)) {
301 Debug(net, 0,
"[crypto] Peer sent an illegal public key; authentication aborted.");
305 if (crypto_aead_unlock(message.data(), mac.data(), this->derived_keys.ClientToServer().data(), this->key_exchange_nonce.data(),
306 this->peer_public_key.data(), this->peer_public_key.size(), message.data(), message.size()) != 0) {
323 this->handler->AskUserForPassword(this->handler);
338 if (secret_key.empty()) {
339 Debug(net, 3,
"[crypto] Creating a new random key");
341 Debug(net, 0,
"[crypto] Found invalid secret key, creating a new random key");
365 auto is_of_method = [method](
Handler &handler) {
return handler->GetAuthenticationMethod() == method; };
371 Debug(net, 9,
"Received {} authentication request", this->
GetName());
377 Debug(net, 9,
"Sending {} authentication response", this->
GetName());
400 if (!handler->CanBeUsed())
return;
402 this->
handlers.push_back(std::move(handler));
407 Debug(net, 9,
"Sending {} authentication request", this->
GetName());
410 this->
handlers.back()->SendRequest(p);
415 Debug(net, 9,
"Receiving {} authentication response", this->
GetName());
462 std::unique_ptr<NetworkAuthenticationClientHandler>
NetworkAuthenticationClientHandler::Create(std::shared_ptr<NetworkAuthenticationPasswordRequestHandler> password_handler, std::string &secret_key, std::string &public_key)
465 auto handler = std::make_unique<CombinedAuthenticationClientHandler>();
466 handler->Add(std::make_unique<X25519KeyExchangeOnlyClientHandler>(secret));
467 handler->Add(std::make_unique<X25519PAKEClientHandler>(secret, std::move(password_handler)));
468 handler->Add(std::make_unique<X25519AuthorizedKeyClientHandler>(secret));
481 auto handler = std::make_unique<CombinedAuthenticationServerHandler>();
483 handler->Add(std::make_unique<X25519PAKEServerHandler>(secret, password_provider));
487 handler->Add(std::make_unique<X25519AuthorizedKeyServerHandler>(secret, authorized_key_handler));
492 handler->Add(std::make_unique<X25519KeyExchangeOnlyServerHandler>(secret));
Container for a X25519 key that is automatically crypto-wiped when destructed.
static std::unique_ptr< NetworkAuthenticationClientHandler > Create(std::shared_ptr< NetworkAuthenticationPasswordRequestHandler > password_handler, std::string &secret_key, std::string &public_key)
Create a NetworkAuthenticationClientHandler.
bool SendResponse(struct Packet &p, std::string_view derived_key_extra_payload)
Perform the key exchange, and when that is correct fill the Packet with the appropriate data.
uint16_t NetworkAuthenticationMethodMask
The mask of authentication methods that can be used.
std::string GetPeerPublicKey() const
Get the public key the peer provided for the key exchange.
bool ReceiveRequest(struct Packet &p)
Read the key exchange data from a Packet that came from the server,.
std::vector< Handler > handlers
The handlers that we can (still) authenticate with.
X25519AuthenticationHandler(const X25519SecretKey &secret_key)
Create the handler, and generate the public keys accordingly.
virtual bool SendResponse(struct Packet &p)=0
Create the response to send to the server.
virtual std::string_view GetName() const override
Get the name of the handler for debug messages.
std::unique_ptr< NetworkAuthenticationClientHandler > Handler
The type of the inner handlers.
virtual std::string_view GetName() const =0
Get the name of the handler for debug messages.
Base class for handling the encryption (or decryption) of a network connection.
Container for a X25519 nonce that is automatically crypto-wiped when destructed.
X25519Nonce key_exchange_nonce
The nonce to prevent replay attacks of the key exchange.
size_t MACSize() const override
Get the size of the MAC (Message Authentication Code) used by the underlying encryption protocol.
~X25519Key()
Ensure the key does not get leaked when we're done with it.
static X25519SecretKey GetValidSecretKeyAndUpdatePublicKey(std::string &secret_key, std::string &public_key)
Get the secret key from the given string.
static std::unique_ptr< NetworkAuthenticationServerHandler > Create(const NetworkAuthenticationPasswordProvider *password_provider, const NetworkAuthenticationAuthorizedKeyHandler *authorized_key_handler, NetworkAuthenticationMethodMask client_supported_method_mask=~static_cast< NetworkAuthenticationMethodMask >(0))
Create a NetworkAuthenticationServerHandler.
X25519EncryptionHandler(const std::span< const uint8_t > key, const X25519Nonce &nonce)
Create the encryption handler.
bool ConvertHexToBytes(std::string_view hex, std::span< uint8_t > bytes)
Convert a hex-string to a byte-array, while validating it was actually hex.
@ SERVER
We are the server.
virtual void SendResponse()=0
Callback to trigger sending the response for the password request.
void Encrypt(std::span< std::uint8_t > mac, std::span< std::uint8_t > message) override
Encrypt the given message in-place, and write the associated MAC.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
size_t Recv_bytes(std::span< uint8_t > span)
Extract at most the length of the span bytes from the packet into the span.
virtual NetworkAuthenticationMethod GetAuthenticationMethod() const override
Get the method this handler is providing functionality for.
virtual RequestResult ReceiveRequest(struct Packet &p)=0
Read a request from the server.
virtual ResponseResult ReceiveResponse(struct Packet &p) override
Read the response from the client.
bool Decrypt(std::span< std::uint8_t > mac, std::span< std::uint8_t > message) override
Decrypt the given message in-place, validating against the given MAC.
constexpr size_t X25519_NONCE_SIZE
The number of bytes the nonces are in X25519.
~X25519Nonce()
Ensure the nonce does not get leaked when we're done with it.
virtual bool CanBeUsed() const override
Checks whether this handler can be used with the current configuration.
@ NETWORK_AUTH_METHOD_X25519_KEY_EXCHANGE_ONLY
No actual authentication is taking place, just perform a x25519 key exchange. This method is not supp...
static void crypto_wipe(std::span< uint8_t > span)
Call crypto_wipe for all the data in the given span.
void Send_uint8(uint8_t data)
Package a 8 bits integer in the packet.
std::span< const uint8_t > ServerToClient() const
Get the key to encrypt or decrypt a message sent from the server to the client.
std::string FormatArrayAsHex(std::span< const uint8_t > data)
Format a byte array into a continuous hex string.
X25519PublicKey peer_public_key
The public key used by our peer.
virtual RequestResult ReceiveRequest(struct Packet &p) override
Read a request from the server.
@ NOT_AUTHENTICATED
All authentications for this handler have been exhausted.
Container for a X25519 public key.
X25519Nonce encryption_nonce
The nonce to prevent replay attacks the encrypted connection.
@ NETWORK_AUTH_METHOD_X25519_PAKE
Authentication using x25519 password-authenticated key agreement.
X25519KeyExchangeSide
The side of the key exchange.
std::array< uint8_t, X25519_KEY_EXCHANGE_MESSAGE_SIZE > X25519KeyExchangeMessage
Container for a X25519 key exchange message.
@ AUTHENTICATED
The client was authenticated successfully.
static void EnsureValidSecretKeyAndUpdatePublicKey(std::string &secret_key, std::string &public_key)
Ensures that the given secret key is valid, and when not overwrite it with a valid secret key.
virtual NetworkAuthenticationMethod GetAuthenticationMethod() const override
Get the method this handler is providing functionality for.
NetworkAuthenticationMethod
The authentication method that can be used.
crypto_aead_ctx context
The actual encryption context.
virtual NetworkAuthenticationMethod GetAuthenticationMethod() const =0
Get the method this handler is providing functionality for.
RequestResult
The processing result of receiving a request.
virtual void SendRequest(struct Packet &p) override
Create the request to send to the client.
Internal entity of a packet.
virtual void Reply(const std::string &password) override
Reply to the request with the given password.
void Add(Handler &&handler)
Add the given sub-handler to this handler, if the handler can be used (e.g.
Encryption handler implementation for monocypther encryption after a X25519 key exchange.
std::array< uint8_t, X25519_MAC_SIZE > X25519Mac
Container for a X25519 message authentication code.
void RandomBytesWithFallback(std::span< uint8_t > buf)
Fill the given buffer with random bytes.
@ AWAIT_USER_INPUT
We have requested some user input, but must wait on that.
@ CLIENT
We are the client.
virtual std::string GetPeerPublicKey() const override
Get the public key the peer provided during the authentication.
std::span< const uint8_t > ClientToServer() const
Get the key to encrypt or decrypt a message sent from the client to the server.
Callback interface for server implementations to provide the current password.
Callback interface for server implementations to provide the authorized key validation.
X25519PublicKey CreatePublicKey() const
Create the public key associated with this secret key.
static X25519Nonce CreateRandom()
Create a new nonce that's filled with random bytes.
ResponseResult
The processing result of receiving a response.
NetworkAuthenticationServerHandler::ResponseResult ReceiveResponse(struct Packet &p, std::string_view derived_key_extra_payload)
Read the key exchange data from a Packet that came from the client, and check whether the client pass...
@ INVALID
We have received an invalid request.
std::unique_ptr< NetworkAuthenticationServerHandler > Handler
The type of the inner handlers.
~X25519EncryptionHandler()
Ensure the encryption context is wiped!
virtual RequestResult ReceiveRequest(struct Packet &p) override
Read a request from the server.
bool ReceiveEnableEncryption(struct Packet &p)
Receive the initial nonce for the encrypted connection.
bool Exchange(const X25519PublicKey &peer_public_key, X25519KeyExchangeSide side, const X25519SecretKey &our_secret_key, const X25519PublicKey &our_public_key, std::string_view extra_payload)
Perform the actual key exchange.
@ NETWORK_AUTH_METHOD_X25519_AUTHORIZED_KEY
Authentication using x22519 key exchange and authorized keys.
constexpr size_t X25519_KEY_EXCHANGE_MESSAGE_SIZE
The number of bytes the (random) payload of the authentication message has.
std::array< uint8_t, X25519_KEY_SIZE+X25519_KEY_SIZE > keys
Single contiguous buffer to store the derived keys in, as they are generated as a single hash.
constexpr size_t X25519_MAC_SIZE
The number of bytes the message authentication codes are in X25519.
std::string password
The entered password.
std::vector< Handler > handlers
The handlers that we can authenticate with.
const NetworkAuthenticationAuthorizedKeyHandler * authorized_key_handler
The handler of the authorized keys.
constexpr size_t X25519_KEY_SIZE
The number of bytes the public and secret keys are in X25519.
@ RETRY_NEXT_METHOD
The client failed to authenticate, but there is another method to try.
@ NETWORK_AUTH_METHOD_END
Must ALWAYS be on the end of this list!! (period)
virtual bool IsAllowed(std::string_view peer_public_key) const =0
Check whether the given public key of the peer is allowed in.
static X25519SecretKey CreateRandom()
Create a new secret key that's filled with random bytes.
~X25519DerivedKeys()
Ensure the derived keys do not get leaked when we're done with it.
virtual ResponseResult ReceiveResponse(struct Packet &p) override
Read the response from the client.
virtual bool SendResponse(struct Packet &p) override
Create the response to send to the server.
virtual std::string_view GetName() const override
Get the name of the handler for debug messages.
size_t RemainingBytesToTransfer() const
Get the amount of bytes that are still available for the Transfer functions.
NetworkAuthenticationClientHandler * current_handler
The currently active handler.
std::span< const uint8_t > Send_bytes(const std::span< const uint8_t > span)
Send as many of the bytes as possible in the packet.
Container for a X25519 secret key.
void SendEnableEncryption(struct Packet &p) const
Send the initial nonce for the encrypted connection.
X25519PublicKey our_public_key
The public key used by us.
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
X25519DerivedKeys derived_keys
Keys derived from the authentication process.
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.