10 #include "../stdafx.h"
12 #include "../3rdparty/catch2/catch.hpp"
14 #include "../core/format.hpp"
15 #include "../network/network_crypto_internal.h"
16 #include "../network/core/packet.h"
17 #include "../string_func.h"
25 MockNetworkSocketHandler(std::unique_ptr<NetworkEncryptionHandler> &&receive = {}, std::unique_ptr<NetworkEncryptionHandler> &&send = {})
40 auto transfer_in = [](
Packet &source,
char *dest_data,
size_t length) {
41 auto transfer_out = [](
char *dest_data,
const char *source_data,
size_t length) {
42 std::copy(source_data, source_data + length, dest_data);
47 dest.TransferIn(transfer_in, source);
49 bool valid = dest.PrepareToRead();
51 return { dest,
valid };
60 void AskUserForPassword(std::shared_ptr<NetworkAuthenticationPasswordRequest> request)
override { request->Reply(this->password); }
71 std::tie(request,
valid) = CreatePacketForReading(request, &mock_socket_handler);
78 std::tie(response,
valid) = CreatePacketForReading(response, &mock_socket_handler);
84 TEST_CASE(
"Authentication_KeyExchangeOnly")
93 static void TestAuthenticationPAKE(std::string server_password, std::string client_password,
103 TEST_CASE(
"Authentication_PAKE")
105 SECTION(
"Correct password") {
109 SECTION(
"Empty password") {
113 SECTION(
"Wrong password") {
132 TEST_CASE(
"Authentication_AuthorizedKey")
138 SECTION(
"Correct public key") {
142 SECTION(
"Incorrect public key") {
148 TEST_CASE(
"Authentication_Combined")
156 valid_authorized_keys.
Add(client_public_key_str);
160 invalid_authorized_keys.
Add(
"not-a-valid-authorized-key");
166 std::string no_password =
"";
168 std::string valid_password =
"sikrit";
170 std::string invalid_password =
"secret";
175 SECTION(
"Invalid authorized keys, invalid password") {
182 SECTION(
"Invalid authorized keys, valid password") {
189 SECTION(
"Valid authorized keys, valid password") {
195 SECTION(
"No authorized keys, invalid password") {
201 SECTION(
"No authorized keys, valid password") {
207 SECTION(
"No authorized keys, no password") {
218 uint64_t sent_value = 0x1234567890ABCDEF;
219 std::set<PacketType> encrypted_packet_types;
221 for (
int i = 0; i < 10; i++) {
222 Packet request(sending_socket_handler, sent_packet_type);
223 request.Send_uint64(sent_value);
225 auto [response,
valid] = CreatePacketForReading(request, receiving_socket_handler);
227 CHECK(response.Recv_uint64() == sent_value);
229 encrypted_packet_types.insert(request.GetPacketType());
242 CHECK(encrypted_packet_types.size() != 1);
246 TEST_CASE(
"Encryption handling")
257 std::tie(packet,
valid) = CreatePacketForReading(packet, &mock_socket_handler);
264 SECTION(
"Encyption happening client -> server") {
265 CheckEncryption(&client_socket_handler, &server_socket_handler);
268 SECTION(
"Encyption happening server -> client") {
269 CheckEncryption(&server_socket_handler, &client_socket_handler);
272 SECTION(
"Unencrypted packet sent causes invalid read packet") {
276 auto [response,
valid] = CreatePacketForReading(request, &client_socket_handler);
Base class for client side cryptographic authentication handlers.
virtual bool ReceiveEnableEncryption(struct Packet &p)=0
Read the request to enable encryption from the server.
virtual RequestResult ReceiveRequest(struct Packet &p)=0
Read a request from the server.
RequestResult
The processing result of receiving a request.
@ READY_FOR_RESPONSE
We do not have to wait for user input, and can immediately respond to the server.
@ AWAIT_USER_INPUT
We have requested some user input, but must wait on that.
virtual bool SendResponse(struct Packet &p)=0
Create the response to send to the server.
static std::unique_ptr< NetworkAuthenticationClientHandler > Create(std::shared_ptr< NetworkAuthenticationPasswordRequestHandler > password_handler, std::string &secret_key, std::string &public_key)
Create a NetworkAuthenticationClientHandler.
Default implementation for the authorized key handler.
Default implementation of the password provider.
virtual std::unique_ptr< NetworkEncryptionHandler > CreateClientToServerEncryptionHandler() const =0
Create a NetworkEncryptionHandler to encrypt or decrypt messages from the client to the server.
virtual std::unique_ptr< NetworkEncryptionHandler > CreateServerToClientEncryptionHandler() const =0
Create a NetworkEncryptionHandler to encrypt or decrypt messages from the server to the client.
Callback interface for client implementations to provide the handling of the password requests.
Base class for server side cryptographic authentication handlers.
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.
virtual ResponseResult ReceiveResponse(struct Packet &p)=0
Read the response from the client.
virtual void SendEnableEncryption(struct Packet &p)=0
Create the request to enable encryption to the client.
ResponseResult
The processing result of receiving a response.
@ RETRY_NEXT_METHOD
The client failed to authenticate, but there is another method to try.
@ AUTHENTICATED
The client was authenticated successfully.
@ NOT_AUTHENTICATED
All authentications for this handler have been exhausted.
virtual void SendRequest(struct Packet &p)=0
Create the request to send to the client.
Simple helper to (more easily) manage authorized keys.
bool Add(std::string_view key)
Add the given key to the authorized keys, when it is not already contained.
SocketHandler for all network sockets in OpenTTD.
std::unique_ptr< class NetworkEncryptionHandler > send_encryption_handler
The handler for encrypting sent packets.
std::unique_ptr< class NetworkEncryptionHandler > receive_encryption_handler
The handler for decrypting received packets.
void SendResponse() override
Callback to trigger sending the response for the password request.
void AskUserForPassword(std::shared_ptr< NetworkAuthenticationPasswordRequest > request) override
Callback to trigger asking the user for the password.
Handler for clients using a X25519 key exchange to perform authentication via a set of authorized (pu...
Handler for servers using a X25519 key exchange to perform authentication via a set of authorized (pu...
Client side handler for using X25519 without actual authentication.
Server side handler for using X25519 without actual authentication.
Client side handler for using X25519 with a password-authenticated key exchange.
Server side handler for using X25519 with a password-authenticated key exchange.
static const uint NETWORK_SECRET_KEY_LENGTH
The maximum length of the hexadecimal encoded secret keys, in bytes including '\0'.
static const size_t COMPAT_MTU
Number of bytes we can pack in a single packet for backward compatibility.
static const uint NETWORK_PUBLIC_KEY_LENGTH
The maximum length of the hexadecimal encoded public keys, in bytes including '\0'.
constexpr size_t X25519_KEY_SIZE
The number of bytes the public and secret keys are in X25519.
uint8_t valid
Bits indicating what variable is valid (for each bit, 0 is invalid, 1 is valid).
uint8_t PacketType
Identifier for the packet.
std::string FormatArrayAsHex(std::span< const uint8_t > data)
Format a byte array into a continuous hex string.
Internal entity of a packet.
size_t Size() const
Get the number of bytes in the packet.
ssize_t TransferOutWithLimit(F transfer_function, size_t limit, D destination, Args &&... args)
Transfer data from the packet to the given function.
void PrepareToSend()
Writes the packet size from the raw packet from packet->size.
void Send_uint64(uint64_t data)
Package a 64 bits integer in the packet.
Container for a X25519 public key.
Container for a X25519 secret key.
X25519PublicKey CreatePublicKey() const
Create the public key associated with this secret key.
static X25519SecretKey CreateRandom()
Create a new secret key that's filled with random bytes.