OpenTTD Source  20240919-master-gdf0233f4c2
X25519AuthenticationHandler Class Reference

Base for handlers using a X25519 key exchange to perform authentication. More...

#include <network_crypto_internal.h>

Inheritance diagram for X25519AuthenticationHandler:
X25519AuthorizedKeyClientHandler X25519AuthorizedKeyServerHandler X25519KeyExchangeOnlyClientHandler X25519KeyExchangeOnlyServerHandler X25519PAKEClientHandler X25519PAKEServerHandler

Protected Member Functions

 X25519AuthenticationHandler (const X25519SecretKey &secret_key)
 Create the handler, and generate the public keys accordingly. More...
 
void SendRequest (struct Packet &p)
 
bool ReceiveRequest (struct Packet &p)
 Read the key exchange data from a Packet that came from the server,. More...
 
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. More...
 
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 passes the key exchange successfully. More...
 
std::string GetPeerPublicKey () const
 Get the public key the peer provided for the key exchange. More...
 
void SendEnableEncryption (struct Packet &p) const
 Send the initial nonce for the encrypted connection. More...
 
bool ReceiveEnableEncryption (struct Packet &p)
 Receive the initial nonce for the encrypted connection. More...
 
std::unique_ptr< NetworkEncryptionHandlerCreateClientToServerEncryptionHandler () const
 
std::unique_ptr< NetworkEncryptionHandlerCreateServerToClientEncryptionHandler () const
 

Private Attributes

X25519SecretKey our_secret_key
 The secret key used by us.
 
X25519PublicKey our_public_key
 The public key used by us.
 
X25519Nonce key_exchange_nonce
 The nonce to prevent replay attacks of the key exchange.
 
X25519DerivedKeys derived_keys
 Keys derived from the authentication process.
 
X25519PublicKey peer_public_key
 The public key used by our peer.
 
X25519Nonce encryption_nonce
 The nonce to prevent replay attacks the encrypted connection.
 

Detailed Description

Base for handlers using a X25519 key exchange to perform authentication.

In general this works as follows: 1) the client and server have or generate a secret and public X25519 key. 2) the X25519 key exchange is performed at both the client and server, with their own secret key and their peer's public key. 3) a pair of derived keys is created by BLAKE2b-hashing the following into 64 bytes, in this particular order:

  • the shared secret from the key exchange;
  • the public key of the server;
  • the public key of the client;
  • optional extra payload, e.g. a password in the case of PAKE. The first of the pair of derived keys is usually used to encrypt client-to-server communication, and the second of the pair is usually used to encrypt server-to-client communication. 4) a XChaCha20-Poly1305 (authenticated) encryption is performed using:
  • the first of the pair of derived keys as encryption key;
  • a 24 byte nonce;
  • the public key of the client as additional authenticated data.
  • a 8 byte random number as content/message.

The server initiates the request by sending its public key and a 24 byte nonce that is randomly generated. Normally the side that sends the encrypted data sends the nonce in their packet, which would be the client on our case. However, there are many implementations of clients due to the admin-protocol where this is used, and we cannot guarantee that they generate a good enough nonce. As such the server sends one instead. The server will create a new set of keys for each session.

The client receives the request, performs the key exchange, generates the derived keys and then encrypts the message. This message must contain some content, so it has to be filled with 8 random bytes. Once the message has been encrypted, the client sends their public key, the encrypted message and the message authentication code (MAC) to the server in a response.

The server receives the response, performs the key exchange, generates the derived keys, decrypts the message and validates the message authentication code, and finally the message. It is up to the sub class to perform the final authentication checks.

Definition at line 104 of file network_crypto_internal.h.

Constructor & Destructor Documentation

◆ X25519AuthenticationHandler()

X25519AuthenticationHandler::X25519AuthenticationHandler ( const X25519SecretKey secret_key)
protected

Create the handler, and generate the public keys accordingly.

Parameters
secret_keyThe secret key to use for this handler. Defaults to secure random data.

Definition at line 184 of file network_crypto.cpp.

Member Function Documentation

◆ GetPeerPublicKey()

std::string X25519AuthenticationHandler::GetPeerPublicKey ( ) const
protected

Get the public key the peer provided for the key exchange.

Returns
The hexadecimal string representation of the peer's public key.

Definition at line 244 of file network_crypto.cpp.

References FormatArrayAsHex(), and peer_public_key.

Referenced by X25519KeyExchangeOnlyServerHandler::GetPeerPublicKey(), X25519PAKEServerHandler::GetPeerPublicKey(), and X25519AuthorizedKeyServerHandler::GetPeerPublicKey().

◆ ReceiveEnableEncryption()

bool X25519AuthenticationHandler::ReceiveEnableEncryption ( struct Packet p)
protected

Receive the initial nonce for the encrypted connection.

Parameters
pThe packet to read the data from.
Returns
true when enough bytes could be read for the nonce, otherwise false.

Definition at line 263 of file network_crypto.cpp.

References encryption_nonce, and Packet::Recv_bytes().

Referenced by X25519KeyExchangeOnlyClientHandler::ReceiveEnableEncryption(), X25519PAKEClientHandler::ReceiveEnableEncryption(), and X25519AuthorizedKeyClientHandler::ReceiveEnableEncryption().

◆ ReceiveRequest()

bool X25519AuthenticationHandler::ReceiveRequest ( struct Packet p)
protected

Read the key exchange data from a Packet that came from the server,.

Parameters
pThe packet that has been received.
Returns
True when the data seems correct.

Definition at line 201 of file network_crypto.cpp.

References Debug, key_exchange_nonce, peer_public_key, Packet::Recv_bytes(), Packet::RemainingBytesToTransfer(), X25519_KEY_SIZE, and X25519_NONCE_SIZE.

Referenced by X25519KeyExchangeOnlyClientHandler::ReceiveRequest(), X25519PAKEClientHandler::ReceiveRequest(), and X25519AuthorizedKeyClientHandler::ReceiveRequest().

◆ ReceiveResponse()

NetworkAuthenticationServerHandler::ResponseResult X25519AuthenticationHandler::ReceiveResponse ( struct Packet p,
std::string_view  derived_key_extra_payload 
)
protected

Read the key exchange data from a Packet that came from the client, and check whether the client passes the key exchange successfully.

Parameters
pThe packet that has been received.
derived_key_extra_payloadThe extra payload to pass to the key exchange.
Returns
Whether the authentication was successful or not.

Definition at line 285 of file network_crypto.cpp.

References NetworkAuthenticationServerHandler::AUTHENTICATED, Debug, derived_keys, X25519DerivedKeys::Exchange(), NetworkAuthenticationServerHandler::NOT_AUTHENTICATED, peer_public_key, Packet::Recv_bytes(), Packet::RemainingBytesToTransfer(), SERVER, X25519_KEY_EXCHANGE_MESSAGE_SIZE, X25519_KEY_SIZE, and X25519_MAC_SIZE.

Referenced by X25519KeyExchangeOnlyServerHandler::ReceiveResponse(), and X25519PAKEServerHandler::ReceiveResponse().

◆ SendEnableEncryption()

void X25519AuthenticationHandler::SendEnableEncryption ( struct Packet p) const
protected

Send the initial nonce for the encrypted connection.

Parameters
pThe packet to send the data in.

Definition at line 253 of file network_crypto.cpp.

References encryption_nonce, and Packet::Send_bytes().

Referenced by X25519KeyExchangeOnlyServerHandler::SendEnableEncryption(), X25519PAKEServerHandler::SendEnableEncryption(), and X25519AuthorizedKeyServerHandler::SendEnableEncryption().

◆ SendResponse()

bool X25519AuthenticationHandler::SendResponse ( struct Packet p,
std::string_view  derived_key_extra_payload 
)
protected

Perform the key exchange, and when that is correct fill the Packet with the appropriate data.

Parameters
pThe packet that has to be sent.
derived_key_extra_payloadThe extra payload to pass to the key exchange.
Returns
Whether the key exchange was successful or not.

Definition at line 219 of file network_crypto.cpp.

References CLIENT, Debug, derived_keys, X25519DerivedKeys::Exchange(), our_public_key, RandomBytesWithFallback(), and Packet::Send_bytes().

Referenced by X25519KeyExchangeOnlyClientHandler::SendResponse(), X25519PAKEClientHandler::SendResponse(), and X25519AuthorizedKeyClientHandler::SendResponse().


The documentation for this class was generated from the following files: