2018-12-14 13:41:00 -05:00
|
|
|
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
Copying //UE4/Dev-Networking to //UE4/Dev-Main (Source: //UE4/Dev-Networking @ 3495493)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3302759 on 2017/02/14 by John.Pollard
Remove invalid replay samples that can occur due to oversampling (sampling at higher rate than physics is being ticked)
Change 3306072 on 2017/02/16 by John.Barrett
Minor NetcodeUnitTest updates/fixes.
Improved assignment for some types, using FVMReflection - added assignment to enum by name.
Change 3322165 on 2017/02/24 by John.Barrett
Fixed issue where Steam would block unit tests. #JIRA UENET-537
Change 3323917 on 2017/02/27 by John.Barrett
Added better unit test log file management. #JIRA UENET-535
Unit test logs are now stored in subfolders in the game log folder, with one main folder for the current UE4 session, and one subfolder for every unit test run during that session.
Logs are purged occasionally, in line with how the main game logs are purged.
Change 3326307 on 2017/02/28 by John.Pollard
Remove unused cvar
Change 3327907 on 2017/03/01 by John.Barrett
Merged some old NetcodeUnitTest debug features:
- Added command for bit-based log dumping of data (for debugging bit-based netcode)
- Added exported function, for allowing access to console commands, in modules which don't import Engine
Change 3332710 on 2017/03/05 by John.Barrett
Updated unit test flags to expect a disconnect when expecting a server crash.
Change 3332715 on 2017/03/05 by John.Barrett
Wrapped all CreateChannelBunch pointers with a nullptr check (used to not be required).
Replaced old/duplicate unit test code (using CreateChannelBunch) for marking 'exploit failure', with the current centralized function calls.
#JIRA UENET-539
Change 3336258 on 2017/03/07 by John.Pollard
Add more info to history overflow logging
Change 3336259 on 2017/03/07 by John.Pollard
Don't pause replication for replay connections
Change 3341288 on 2017/03/10 by John.Barrett
Fixed invalid access to GLog during game shutdown. #JIRA UE-42394
Change 3341736 on 2017/03/10 by John.Pollard
Get reliability packet handler working again (but still disabled by default)
Change 3349298 on 2017/03/16 by John.Barrett
Fixed issues/potential-issues with the timing of global variable destruction, based on Graeme Thornton's fix. #JIRA UE-42394
Change 3349393 on 2017/03/16 by John.Pollard
Reliability handler cleanup
Change 3350029 on 2017/03/16 by John.Barrett
Updated PacketHandler to support an optional handshaking stage for HandlerComponents, where each handshake must execute sequentially starting at the component closest to the socket.
Change 3350030 on 2017/03/16 by John.Barrett
Updated Asymetric Encryption to support updated PacketHandler system, to perform a key handshake that is compatible with other HandlerComponent's, and fixed some serialization security issues by setting proper limits on values.
Change 3350032 on 2017/03/16 by John.Barrett
Minor corrections to variable types and constructor initializer lists, for the rest of the encryption code.
Change 3355536 on 2017/03/20 by John.Barrett
Added new PacketAudit debug feature, which uses inter-process-communication, to audit the integrity of incoming/outgoing packets at various stages of serialization, between a client and server.
This is critically useful for low level netcode development, particularly with the PacketHandler.
See PacketAudit.h for more information.
Change 3355570 on 2017/03/20 by John.Barrett
Added a small number packet auditing checks to key areas of low level netcode.
Change 3355584 on 2017/03/20 by John.Barrett
Updated ReliabilityHandlerComponent, to support packet reliability during the PacketHandler handshaking stage, and fixed ReliabilityHandlerComponent serializing based on a packets byte size, rather than bit size.
Change 3373389 on 2017/03/30 by John.Barrett
Added check for HandlerComponent's that require reliability.
Change 3373390 on 2017/03/30 by John.Barrett
Added TLS-like encryption handler component, which exchanges a secret key using asymmetric encryption (RSA), and implements symmetric encryption using that key (AES).
Based on RSA encryption component, and John Pollard's AES changes.
Enable in *Engine.ini, using:
[PacketHandlerComponents]
Components=RSAKeyAESEncryption
bEnableReliability=true
Change 3394518 on 2017/04/14 by Ryan.Gerleve
Fix memory leak in FRepChangelistState: added destructor that properly destroys the properties in the shadow state buffer.
Change 3432955 on 2017/05/10 by John.Barrett
Randomized the initial packet sequence numbers for UNetConnection's and for reliable packets - using the stateless handshake cookie.
Also added hooks to determine when PacketHandler level handshaking has completed, so that the initial connection packets can be delayed until this stage (required now, in order to exchange the sequence numbers first).
Change 3464528 on 2017/05/29 by John.Barrett
Fixed connection failure during unreliable network conditions, caused by a bad interaction between the stateless handshake and sequence initialization code.
Added a new 'ack' stage to the stateless handshake, to ensure the client/server sequence is properly synchronised.
Expanded the timeout/retry handling for the stateless handshake, so it is more robust, and fixed some bugs in this code.
Change 3464537 on 2017/05/29 by John.Barrett
Fixed an incompatibility between the asymmetric encryption, and the new PacketHandler handshake code.
Change 3464543 on 2017/05/29 by John.Barrett
Updated CryptoPP to 5.6.5.
Change 3467529 on 2017/05/31 by Jon.Nabozny
Add comments to FPacketSimulationSettings vars.
Change 3469584 on 2017/06/01 by Ryan.Gerleve
Log bunch ChSequence on reliable channel open along with other info.
Change 3471329 on 2017/06/02 by John.Barrett
Fixed PacketHandlerLog type not being exported.
Change 3471875 on 2017/06/02 by John.Barrett
Fixed code that was trying to send NetConnection packets from the server to the client, too early - and tidied up related checks.
#JIRA UE-45637
Change 3473030 on 2017/06/04 by John.Barrett
Fixed replay incomaptibility with recent sequence/handshake changes.
Change 3476313 on 2017/06/06 by Ryan.Gerleve
Add initial reliable sequence numbers to the log in UNetConnection::InitSequence.
Change 3478649 on 2017/06/07 by Ryan.Gerleve
Add additional logging for the case where a channel open command is received by a channel that's already opened locally.
Change 3482926 on 2017/06/09 by John.Barrett
First pass at Minimal Client refactor for NetcodeUnitTest - split basic/minimal client code out of ClientUnitTest, into its own class - while preserving existing ClientUnitTest interface.
This will allow multiple minimal clients per unit test, where only one could be used before (necessary for games that require a beacon + game connection).
Added reflection support for weak UObject properties.
Added MCP requirements flag for unit tests.
Process pipe reading tweaks, to avoid UI freezes.
Change 3485179 on 2017/06/12 by Ryan.Gerleve
Add backwards-compatibility macros for random initial packet sequence changes so that game plugins can check them.
Change 3489040 on 2017/06/14 by John.Barrett
Removed OnlineSubsystem dependencies.
[CL 3495525 by Ryan Gerleve in Main branch]
2017-06-16 14:10:35 -04:00
|
|
|
|
|
|
|
|
#include "RSAKeyAESEncryptionHandlerComponent.h"
|
|
|
|
|
|
|
|
|
|
#include "PacketAudit.h"
|
|
|
|
|
#include "PacketHandler.h"
|
|
|
|
|
|
|
|
|
|
#include "Modules/ModuleManager.h"
|
|
|
|
|
#include "UObject/CoreNet.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IMPLEMENT_MODULE(FRSAKeyAESEncryptionModuleInterface, RSAKeyAESEncryption);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// @todo #JohnB: IMPORTANT: See if you can replace CryptoPP with OpenSSL API's instead, as that makes it easier for platform teams
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// @todo #JohnB: Add/test support for CanReadUnaligned.
|
|
|
|
|
|
|
|
|
|
// @todo #JohnB: The entire encryption implementation should be very carefully audited, and something like DTLS reviewed,
|
|
|
|
|
// and a new document written up on how encryption would be implemented from scratch
|
|
|
|
|
// (starting from the stateless handshake code), and then compared against this
|
|
|
|
|
|
|
|
|
|
// @todo #JohnB: Add supporting for increasing 'AsymmetricKeySize' to 4096 - currently, this triggers a limit with MaxOutgoingBits,
|
|
|
|
|
// and thus is limited to 2048, until the code is expanded to support values greater than this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Defines
|
|
|
|
|
|
|
|
|
|
/** Puts a limit on the maximum size of the exponent. */
|
|
|
|
|
// @todo: This should be limited further, as a high exponent could potentially be used for performing a DoS attack,
|
|
|
|
|
// by making it very costly to decrypt packets. The limit is only this high temporarily.
|
|
|
|
|
#define MAX_EXPONENT_BITS 1024
|
|
|
|
|
|
|
|
|
|
#define AES_BLOCK_SIZE 16
|
|
|
|
|
|
|
|
|
|
/** The maximum size for a packet being compressed */
|
|
|
|
|
// @todo #JohnB: This actually overshoots the maximum, and should probably be refined further
|
|
|
|
|
#define MAX_COMPRESSED_PACKET_SIZE (MAX_PACKET_SIZE * 8)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handshake sequence:
|
|
|
|
|
* Server Client
|
|
|
|
|
*
|
|
|
|
|
* AsymmetricKey = Rand()
|
|
|
|
|
*
|
|
|
|
|
* [AsymmetricKey] ->
|
|
|
|
|
*
|
|
|
|
|
* SessionKey = Rand()
|
|
|
|
|
* EncryptedSessionKey = Encrypt(SessionKey, AsymmetricKey)
|
|
|
|
|
*
|
|
|
|
|
* <- [EncryptedSessionKey]
|
|
|
|
|
*
|
|
|
|
|
* *Handshake Complete*
|
|
|
|
|
*
|
|
|
|
|
* SessionKey=Decrypt(SessionKey, AsymmetricKey)
|
|
|
|
|
*
|
|
|
|
|
* *Handshake Complete*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* RSAKeyAESEncryptionHandlerComponent
|
|
|
|
|
*/
|
|
|
|
|
RSAKeyAESEncryptionHandlerComponent::RSAKeyAESEncryptionHandlerComponent(uint32 InAsymmetricKeySize, uint32 InSessionKeySize)
|
|
|
|
|
: AsymmetricKeyMaxPlaintextLength(0)
|
|
|
|
|
, AsymmetricKeyFixedCiphertextLength(0)
|
|
|
|
|
, AsymmetricKeySize(InAsymmetricKeySize)
|
|
|
|
|
, SessionKeySize(InSessionKeySize)
|
|
|
|
|
, State(ERSAKeyAESEncryptionHandler::State::UnInitialized)
|
|
|
|
|
, AsymmetricRng()
|
|
|
|
|
, Params()
|
|
|
|
|
, AsymmetricEncrypt()
|
|
|
|
|
, AsymmetricDecrypt()
|
|
|
|
|
, PublicKey()
|
|
|
|
|
, PrivateKey()
|
|
|
|
|
, SymmetricEncrypt()
|
|
|
|
|
, SymmetricDecrypt()
|
|
|
|
|
{
|
|
|
|
|
SetActive(true);
|
|
|
|
|
|
|
|
|
|
bRequiresHandshake = true;
|
|
|
|
|
bRequiresReliability = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::Initialize()
|
|
|
|
|
{
|
|
|
|
|
Params.GenerateRandomWithKeySize(AsymmetricRng, AsymmetricKeySize);
|
|
|
|
|
|
|
|
|
|
PublicKey = CryptoPP::RSA::PublicKey(Params);
|
|
|
|
|
PrivateKey = CryptoPP::RSA::PrivateKey(Params);
|
|
|
|
|
AsymmetricEncrypt = CryptoPP::RSAES_OAEP_SHA_Encryptor(PrivateKey);
|
|
|
|
|
AsymmetricDecrypt = CryptoPP::RSAES_OAEP_SHA_Decryptor(PrivateKey);
|
|
|
|
|
AsymmetricKeyMaxPlaintextLength = static_cast<uint32>(AsymmetricEncrypt.FixedMaxPlaintextLength());
|
|
|
|
|
AsymmetricKeyFixedCiphertextLength = static_cast<uint32>(AsymmetricEncrypt.FixedCiphertextLength());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::NotifyHandshakeBegin()
|
|
|
|
|
{
|
|
|
|
|
// The server sends the asymmetric key
|
|
|
|
|
if (Handler->Mode == Handler::Mode::Server)
|
|
|
|
|
{
|
|
|
|
|
FBitWriter OutPacket;
|
2018-09-25 10:11:35 -04:00
|
|
|
FOutPacketTraits Traits;
|
Copying //UE4/Dev-Networking to //UE4/Dev-Main (Source: //UE4/Dev-Networking @ 3495493)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3302759 on 2017/02/14 by John.Pollard
Remove invalid replay samples that can occur due to oversampling (sampling at higher rate than physics is being ticked)
Change 3306072 on 2017/02/16 by John.Barrett
Minor NetcodeUnitTest updates/fixes.
Improved assignment for some types, using FVMReflection - added assignment to enum by name.
Change 3322165 on 2017/02/24 by John.Barrett
Fixed issue where Steam would block unit tests. #JIRA UENET-537
Change 3323917 on 2017/02/27 by John.Barrett
Added better unit test log file management. #JIRA UENET-535
Unit test logs are now stored in subfolders in the game log folder, with one main folder for the current UE4 session, and one subfolder for every unit test run during that session.
Logs are purged occasionally, in line with how the main game logs are purged.
Change 3326307 on 2017/02/28 by John.Pollard
Remove unused cvar
Change 3327907 on 2017/03/01 by John.Barrett
Merged some old NetcodeUnitTest debug features:
- Added command for bit-based log dumping of data (for debugging bit-based netcode)
- Added exported function, for allowing access to console commands, in modules which don't import Engine
Change 3332710 on 2017/03/05 by John.Barrett
Updated unit test flags to expect a disconnect when expecting a server crash.
Change 3332715 on 2017/03/05 by John.Barrett
Wrapped all CreateChannelBunch pointers with a nullptr check (used to not be required).
Replaced old/duplicate unit test code (using CreateChannelBunch) for marking 'exploit failure', with the current centralized function calls.
#JIRA UENET-539
Change 3336258 on 2017/03/07 by John.Pollard
Add more info to history overflow logging
Change 3336259 on 2017/03/07 by John.Pollard
Don't pause replication for replay connections
Change 3341288 on 2017/03/10 by John.Barrett
Fixed invalid access to GLog during game shutdown. #JIRA UE-42394
Change 3341736 on 2017/03/10 by John.Pollard
Get reliability packet handler working again (but still disabled by default)
Change 3349298 on 2017/03/16 by John.Barrett
Fixed issues/potential-issues with the timing of global variable destruction, based on Graeme Thornton's fix. #JIRA UE-42394
Change 3349393 on 2017/03/16 by John.Pollard
Reliability handler cleanup
Change 3350029 on 2017/03/16 by John.Barrett
Updated PacketHandler to support an optional handshaking stage for HandlerComponents, where each handshake must execute sequentially starting at the component closest to the socket.
Change 3350030 on 2017/03/16 by John.Barrett
Updated Asymetric Encryption to support updated PacketHandler system, to perform a key handshake that is compatible with other HandlerComponent's, and fixed some serialization security issues by setting proper limits on values.
Change 3350032 on 2017/03/16 by John.Barrett
Minor corrections to variable types and constructor initializer lists, for the rest of the encryption code.
Change 3355536 on 2017/03/20 by John.Barrett
Added new PacketAudit debug feature, which uses inter-process-communication, to audit the integrity of incoming/outgoing packets at various stages of serialization, between a client and server.
This is critically useful for low level netcode development, particularly with the PacketHandler.
See PacketAudit.h for more information.
Change 3355570 on 2017/03/20 by John.Barrett
Added a small number packet auditing checks to key areas of low level netcode.
Change 3355584 on 2017/03/20 by John.Barrett
Updated ReliabilityHandlerComponent, to support packet reliability during the PacketHandler handshaking stage, and fixed ReliabilityHandlerComponent serializing based on a packets byte size, rather than bit size.
Change 3373389 on 2017/03/30 by John.Barrett
Added check for HandlerComponent's that require reliability.
Change 3373390 on 2017/03/30 by John.Barrett
Added TLS-like encryption handler component, which exchanges a secret key using asymmetric encryption (RSA), and implements symmetric encryption using that key (AES).
Based on RSA encryption component, and John Pollard's AES changes.
Enable in *Engine.ini, using:
[PacketHandlerComponents]
Components=RSAKeyAESEncryption
bEnableReliability=true
Change 3394518 on 2017/04/14 by Ryan.Gerleve
Fix memory leak in FRepChangelistState: added destructor that properly destroys the properties in the shadow state buffer.
Change 3432955 on 2017/05/10 by John.Barrett
Randomized the initial packet sequence numbers for UNetConnection's and for reliable packets - using the stateless handshake cookie.
Also added hooks to determine when PacketHandler level handshaking has completed, so that the initial connection packets can be delayed until this stage (required now, in order to exchange the sequence numbers first).
Change 3464528 on 2017/05/29 by John.Barrett
Fixed connection failure during unreliable network conditions, caused by a bad interaction between the stateless handshake and sequence initialization code.
Added a new 'ack' stage to the stateless handshake, to ensure the client/server sequence is properly synchronised.
Expanded the timeout/retry handling for the stateless handshake, so it is more robust, and fixed some bugs in this code.
Change 3464537 on 2017/05/29 by John.Barrett
Fixed an incompatibility between the asymmetric encryption, and the new PacketHandler handshake code.
Change 3464543 on 2017/05/29 by John.Barrett
Updated CryptoPP to 5.6.5.
Change 3467529 on 2017/05/31 by Jon.Nabozny
Add comments to FPacketSimulationSettings vars.
Change 3469584 on 2017/06/01 by Ryan.Gerleve
Log bunch ChSequence on reliable channel open along with other info.
Change 3471329 on 2017/06/02 by John.Barrett
Fixed PacketHandlerLog type not being exported.
Change 3471875 on 2017/06/02 by John.Barrett
Fixed code that was trying to send NetConnection packets from the server to the client, too early - and tidied up related checks.
#JIRA UE-45637
Change 3473030 on 2017/06/04 by John.Barrett
Fixed replay incomaptibility with recent sequence/handshake changes.
Change 3476313 on 2017/06/06 by Ryan.Gerleve
Add initial reliable sequence numbers to the log in UNetConnection::InitSequence.
Change 3478649 on 2017/06/07 by Ryan.Gerleve
Add additional logging for the case where a channel open command is received by a channel that's already opened locally.
Change 3482926 on 2017/06/09 by John.Barrett
First pass at Minimal Client refactor for NetcodeUnitTest - split basic/minimal client code out of ClientUnitTest, into its own class - while preserving existing ClientUnitTest interface.
This will allow multiple minimal clients per unit test, where only one could be used before (necessary for games that require a beacon + game connection).
Added reflection support for weak UObject properties.
Added MCP requirements flag for unit tests.
Process pipe reading tweaks, to avoid UI freezes.
Change 3485179 on 2017/06/12 by Ryan.Gerleve
Add backwards-compatibility macros for random initial packet sequence changes so that game plugins can check them.
Change 3489040 on 2017/06/14 by John.Barrett
Removed OnlineSubsystem dependencies.
[CL 3495525 by Ryan Gerleve in Main branch]
2017-06-16 14:10:35 -04:00
|
|
|
|
|
|
|
|
PackAsymmetricKey(OutPacket);
|
|
|
|
|
SetState(ERSAKeyAESEncryptionHandler::State::SentKey);
|
|
|
|
|
|
|
|
|
|
FPacketAudit::AddStage(TEXT("RSAHandshake"), OutPacket);
|
|
|
|
|
|
2018-09-25 10:11:35 -04:00
|
|
|
Handler->SendHandlerPacket(this, OutPacket, Traits);
|
Copying //UE4/Dev-Networking to //UE4/Dev-Main (Source: //UE4/Dev-Networking @ 3495493)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3302759 on 2017/02/14 by John.Pollard
Remove invalid replay samples that can occur due to oversampling (sampling at higher rate than physics is being ticked)
Change 3306072 on 2017/02/16 by John.Barrett
Minor NetcodeUnitTest updates/fixes.
Improved assignment for some types, using FVMReflection - added assignment to enum by name.
Change 3322165 on 2017/02/24 by John.Barrett
Fixed issue where Steam would block unit tests. #JIRA UENET-537
Change 3323917 on 2017/02/27 by John.Barrett
Added better unit test log file management. #JIRA UENET-535
Unit test logs are now stored in subfolders in the game log folder, with one main folder for the current UE4 session, and one subfolder for every unit test run during that session.
Logs are purged occasionally, in line with how the main game logs are purged.
Change 3326307 on 2017/02/28 by John.Pollard
Remove unused cvar
Change 3327907 on 2017/03/01 by John.Barrett
Merged some old NetcodeUnitTest debug features:
- Added command for bit-based log dumping of data (for debugging bit-based netcode)
- Added exported function, for allowing access to console commands, in modules which don't import Engine
Change 3332710 on 2017/03/05 by John.Barrett
Updated unit test flags to expect a disconnect when expecting a server crash.
Change 3332715 on 2017/03/05 by John.Barrett
Wrapped all CreateChannelBunch pointers with a nullptr check (used to not be required).
Replaced old/duplicate unit test code (using CreateChannelBunch) for marking 'exploit failure', with the current centralized function calls.
#JIRA UENET-539
Change 3336258 on 2017/03/07 by John.Pollard
Add more info to history overflow logging
Change 3336259 on 2017/03/07 by John.Pollard
Don't pause replication for replay connections
Change 3341288 on 2017/03/10 by John.Barrett
Fixed invalid access to GLog during game shutdown. #JIRA UE-42394
Change 3341736 on 2017/03/10 by John.Pollard
Get reliability packet handler working again (but still disabled by default)
Change 3349298 on 2017/03/16 by John.Barrett
Fixed issues/potential-issues with the timing of global variable destruction, based on Graeme Thornton's fix. #JIRA UE-42394
Change 3349393 on 2017/03/16 by John.Pollard
Reliability handler cleanup
Change 3350029 on 2017/03/16 by John.Barrett
Updated PacketHandler to support an optional handshaking stage for HandlerComponents, where each handshake must execute sequentially starting at the component closest to the socket.
Change 3350030 on 2017/03/16 by John.Barrett
Updated Asymetric Encryption to support updated PacketHandler system, to perform a key handshake that is compatible with other HandlerComponent's, and fixed some serialization security issues by setting proper limits on values.
Change 3350032 on 2017/03/16 by John.Barrett
Minor corrections to variable types and constructor initializer lists, for the rest of the encryption code.
Change 3355536 on 2017/03/20 by John.Barrett
Added new PacketAudit debug feature, which uses inter-process-communication, to audit the integrity of incoming/outgoing packets at various stages of serialization, between a client and server.
This is critically useful for low level netcode development, particularly with the PacketHandler.
See PacketAudit.h for more information.
Change 3355570 on 2017/03/20 by John.Barrett
Added a small number packet auditing checks to key areas of low level netcode.
Change 3355584 on 2017/03/20 by John.Barrett
Updated ReliabilityHandlerComponent, to support packet reliability during the PacketHandler handshaking stage, and fixed ReliabilityHandlerComponent serializing based on a packets byte size, rather than bit size.
Change 3373389 on 2017/03/30 by John.Barrett
Added check for HandlerComponent's that require reliability.
Change 3373390 on 2017/03/30 by John.Barrett
Added TLS-like encryption handler component, which exchanges a secret key using asymmetric encryption (RSA), and implements symmetric encryption using that key (AES).
Based on RSA encryption component, and John Pollard's AES changes.
Enable in *Engine.ini, using:
[PacketHandlerComponents]
Components=RSAKeyAESEncryption
bEnableReliability=true
Change 3394518 on 2017/04/14 by Ryan.Gerleve
Fix memory leak in FRepChangelistState: added destructor that properly destroys the properties in the shadow state buffer.
Change 3432955 on 2017/05/10 by John.Barrett
Randomized the initial packet sequence numbers for UNetConnection's and for reliable packets - using the stateless handshake cookie.
Also added hooks to determine when PacketHandler level handshaking has completed, so that the initial connection packets can be delayed until this stage (required now, in order to exchange the sequence numbers first).
Change 3464528 on 2017/05/29 by John.Barrett
Fixed connection failure during unreliable network conditions, caused by a bad interaction between the stateless handshake and sequence initialization code.
Added a new 'ack' stage to the stateless handshake, to ensure the client/server sequence is properly synchronised.
Expanded the timeout/retry handling for the stateless handshake, so it is more robust, and fixed some bugs in this code.
Change 3464537 on 2017/05/29 by John.Barrett
Fixed an incompatibility between the asymmetric encryption, and the new PacketHandler handshake code.
Change 3464543 on 2017/05/29 by John.Barrett
Updated CryptoPP to 5.6.5.
Change 3467529 on 2017/05/31 by Jon.Nabozny
Add comments to FPacketSimulationSettings vars.
Change 3469584 on 2017/06/01 by Ryan.Gerleve
Log bunch ChSequence on reliable channel open along with other info.
Change 3471329 on 2017/06/02 by John.Barrett
Fixed PacketHandlerLog type not being exported.
Change 3471875 on 2017/06/02 by John.Barrett
Fixed code that was trying to send NetConnection packets from the server to the client, too early - and tidied up related checks.
#JIRA UE-45637
Change 3473030 on 2017/06/04 by John.Barrett
Fixed replay incomaptibility with recent sequence/handshake changes.
Change 3476313 on 2017/06/06 by Ryan.Gerleve
Add initial reliable sequence numbers to the log in UNetConnection::InitSequence.
Change 3478649 on 2017/06/07 by Ryan.Gerleve
Add additional logging for the case where a channel open command is received by a channel that's already opened locally.
Change 3482926 on 2017/06/09 by John.Barrett
First pass at Minimal Client refactor for NetcodeUnitTest - split basic/minimal client code out of ClientUnitTest, into its own class - while preserving existing ClientUnitTest interface.
This will allow multiple minimal clients per unit test, where only one could be used before (necessary for games that require a beacon + game connection).
Added reflection support for weak UObject properties.
Added MCP requirements flag for unit tests.
Process pipe reading tweaks, to avoid UI freezes.
Change 3485179 on 2017/06/12 by Ryan.Gerleve
Add backwards-compatibility macros for random initial packet sequence changes so that game plugins can check them.
Change 3489040 on 2017/06/14 by John.Barrett
Removed OnlineSubsystem dependencies.
[CL 3495525 by Ryan Gerleve in Main branch]
2017-06-16 14:10:35 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RSAKeyAESEncryptionHandlerComponent::IsValid() const
|
|
|
|
|
{
|
|
|
|
|
return AsymmetricKeyMaxPlaintextLength > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::SetState(ERSAKeyAESEncryptionHandler::State InState)
|
|
|
|
|
{
|
|
|
|
|
State = InState;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-25 10:11:35 -04:00
|
|
|
void RSAKeyAESEncryptionHandlerComponent::Outgoing(FBitWriter& Packet, FOutPacketTraits& Traits)
|
Copying //UE4/Dev-Networking to //UE4/Dev-Main (Source: //UE4/Dev-Networking @ 3495493)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3302759 on 2017/02/14 by John.Pollard
Remove invalid replay samples that can occur due to oversampling (sampling at higher rate than physics is being ticked)
Change 3306072 on 2017/02/16 by John.Barrett
Minor NetcodeUnitTest updates/fixes.
Improved assignment for some types, using FVMReflection - added assignment to enum by name.
Change 3322165 on 2017/02/24 by John.Barrett
Fixed issue where Steam would block unit tests. #JIRA UENET-537
Change 3323917 on 2017/02/27 by John.Barrett
Added better unit test log file management. #JIRA UENET-535
Unit test logs are now stored in subfolders in the game log folder, with one main folder for the current UE4 session, and one subfolder for every unit test run during that session.
Logs are purged occasionally, in line with how the main game logs are purged.
Change 3326307 on 2017/02/28 by John.Pollard
Remove unused cvar
Change 3327907 on 2017/03/01 by John.Barrett
Merged some old NetcodeUnitTest debug features:
- Added command for bit-based log dumping of data (for debugging bit-based netcode)
- Added exported function, for allowing access to console commands, in modules which don't import Engine
Change 3332710 on 2017/03/05 by John.Barrett
Updated unit test flags to expect a disconnect when expecting a server crash.
Change 3332715 on 2017/03/05 by John.Barrett
Wrapped all CreateChannelBunch pointers with a nullptr check (used to not be required).
Replaced old/duplicate unit test code (using CreateChannelBunch) for marking 'exploit failure', with the current centralized function calls.
#JIRA UENET-539
Change 3336258 on 2017/03/07 by John.Pollard
Add more info to history overflow logging
Change 3336259 on 2017/03/07 by John.Pollard
Don't pause replication for replay connections
Change 3341288 on 2017/03/10 by John.Barrett
Fixed invalid access to GLog during game shutdown. #JIRA UE-42394
Change 3341736 on 2017/03/10 by John.Pollard
Get reliability packet handler working again (but still disabled by default)
Change 3349298 on 2017/03/16 by John.Barrett
Fixed issues/potential-issues with the timing of global variable destruction, based on Graeme Thornton's fix. #JIRA UE-42394
Change 3349393 on 2017/03/16 by John.Pollard
Reliability handler cleanup
Change 3350029 on 2017/03/16 by John.Barrett
Updated PacketHandler to support an optional handshaking stage for HandlerComponents, where each handshake must execute sequentially starting at the component closest to the socket.
Change 3350030 on 2017/03/16 by John.Barrett
Updated Asymetric Encryption to support updated PacketHandler system, to perform a key handshake that is compatible with other HandlerComponent's, and fixed some serialization security issues by setting proper limits on values.
Change 3350032 on 2017/03/16 by John.Barrett
Minor corrections to variable types and constructor initializer lists, for the rest of the encryption code.
Change 3355536 on 2017/03/20 by John.Barrett
Added new PacketAudit debug feature, which uses inter-process-communication, to audit the integrity of incoming/outgoing packets at various stages of serialization, between a client and server.
This is critically useful for low level netcode development, particularly with the PacketHandler.
See PacketAudit.h for more information.
Change 3355570 on 2017/03/20 by John.Barrett
Added a small number packet auditing checks to key areas of low level netcode.
Change 3355584 on 2017/03/20 by John.Barrett
Updated ReliabilityHandlerComponent, to support packet reliability during the PacketHandler handshaking stage, and fixed ReliabilityHandlerComponent serializing based on a packets byte size, rather than bit size.
Change 3373389 on 2017/03/30 by John.Barrett
Added check for HandlerComponent's that require reliability.
Change 3373390 on 2017/03/30 by John.Barrett
Added TLS-like encryption handler component, which exchanges a secret key using asymmetric encryption (RSA), and implements symmetric encryption using that key (AES).
Based on RSA encryption component, and John Pollard's AES changes.
Enable in *Engine.ini, using:
[PacketHandlerComponents]
Components=RSAKeyAESEncryption
bEnableReliability=true
Change 3394518 on 2017/04/14 by Ryan.Gerleve
Fix memory leak in FRepChangelistState: added destructor that properly destroys the properties in the shadow state buffer.
Change 3432955 on 2017/05/10 by John.Barrett
Randomized the initial packet sequence numbers for UNetConnection's and for reliable packets - using the stateless handshake cookie.
Also added hooks to determine when PacketHandler level handshaking has completed, so that the initial connection packets can be delayed until this stage (required now, in order to exchange the sequence numbers first).
Change 3464528 on 2017/05/29 by John.Barrett
Fixed connection failure during unreliable network conditions, caused by a bad interaction between the stateless handshake and sequence initialization code.
Added a new 'ack' stage to the stateless handshake, to ensure the client/server sequence is properly synchronised.
Expanded the timeout/retry handling for the stateless handshake, so it is more robust, and fixed some bugs in this code.
Change 3464537 on 2017/05/29 by John.Barrett
Fixed an incompatibility between the asymmetric encryption, and the new PacketHandler handshake code.
Change 3464543 on 2017/05/29 by John.Barrett
Updated CryptoPP to 5.6.5.
Change 3467529 on 2017/05/31 by Jon.Nabozny
Add comments to FPacketSimulationSettings vars.
Change 3469584 on 2017/06/01 by Ryan.Gerleve
Log bunch ChSequence on reliable channel open along with other info.
Change 3471329 on 2017/06/02 by John.Barrett
Fixed PacketHandlerLog type not being exported.
Change 3471875 on 2017/06/02 by John.Barrett
Fixed code that was trying to send NetConnection packets from the server to the client, too early - and tidied up related checks.
#JIRA UE-45637
Change 3473030 on 2017/06/04 by John.Barrett
Fixed replay incomaptibility with recent sequence/handshake changes.
Change 3476313 on 2017/06/06 by Ryan.Gerleve
Add initial reliable sequence numbers to the log in UNetConnection::InitSequence.
Change 3478649 on 2017/06/07 by Ryan.Gerleve
Add additional logging for the case where a channel open command is received by a channel that's already opened locally.
Change 3482926 on 2017/06/09 by John.Barrett
First pass at Minimal Client refactor for NetcodeUnitTest - split basic/minimal client code out of ClientUnitTest, into its own class - while preserving existing ClientUnitTest interface.
This will allow multiple minimal clients per unit test, where only one could be used before (necessary for games that require a beacon + game connection).
Added reflection support for weak UObject properties.
Added MCP requirements flag for unit tests.
Process pipe reading tweaks, to avoid UI freezes.
Change 3485179 on 2017/06/12 by Ryan.Gerleve
Add backwards-compatibility macros for random initial packet sequence changes so that game plugins can check them.
Change 3489040 on 2017/06/14 by John.Barrett
Removed OnlineSubsystem dependencies.
[CL 3495525 by Ryan Gerleve in Main branch]
2017-06-16 14:10:35 -04:00
|
|
|
{
|
|
|
|
|
if (State == ERSAKeyAESEncryptionHandler::State::Initialized)
|
|
|
|
|
{
|
|
|
|
|
int32 PacketNumBytes = Packet.GetNumBytes();
|
|
|
|
|
|
|
|
|
|
if (PacketNumBytes > 0)
|
|
|
|
|
{
|
|
|
|
|
// Pad along 16 byte boundary, in order to encrypt properly
|
|
|
|
|
// @todo: Review the 16 byte boundary requirement
|
|
|
|
|
uint32 NumberOfBitsInPlaintext = Packet.GetNumBits();
|
|
|
|
|
int32 PaddedSize = (PacketNumBytes + 15) / 16 * 16;
|
|
|
|
|
TArray<uint8> PaddedPlainText;
|
|
|
|
|
TArray<uint8> CipherText;
|
|
|
|
|
|
|
|
|
|
PaddedPlainText.AddUninitialized(PaddedSize);
|
|
|
|
|
CipherText.AddUninitialized(PaddedSize);
|
|
|
|
|
|
|
|
|
|
FMemory::Memcpy(PaddedPlainText.GetData(), Packet.GetData(), PacketNumBytes);
|
|
|
|
|
|
|
|
|
|
if (PaddedSize > PacketNumBytes)
|
|
|
|
|
{
|
|
|
|
|
FMemory::Memzero(PaddedPlainText.GetData() + PacketNumBytes, (PaddedSize - PacketNumBytes));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SymmetricEncrypt.ProcessData(CipherText.GetData(), PaddedPlainText.GetData(), PaddedSize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// @todo: Optimize this.
|
|
|
|
|
Packet.Reset();
|
|
|
|
|
|
|
|
|
|
NumberOfBitsInPlaintext--;
|
|
|
|
|
Packet.SerializeInt(NumberOfBitsInPlaintext, MAX_COMPRESSED_PACKET_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Packet.Serialize(CipherText.GetData(), PaddedSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Warning, TEXT("RSAEncryptionHandlerComponent: Got outgoing packet when not yet initialized."));
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
Packet.SetError();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::Incoming(FBitReader& Packet)
|
|
|
|
|
{
|
|
|
|
|
if (State == ERSAKeyAESEncryptionHandler::State::Initialized)
|
|
|
|
|
{
|
|
|
|
|
uint32 NumberOfBitsInPlaintext = 0;
|
|
|
|
|
|
|
|
|
|
Packet.SerializeInt(NumberOfBitsInPlaintext, MAX_COMPRESSED_PACKET_SIZE);
|
|
|
|
|
NumberOfBitsInPlaintext++;
|
|
|
|
|
|
|
|
|
|
if (!Packet.IsError())
|
|
|
|
|
{
|
|
|
|
|
if (NumberOfBitsInPlaintext <= MAX_COMPRESSED_PACKET_SIZE)
|
|
|
|
|
{
|
|
|
|
|
int32 NumberOfBytesInPlaintext = (NumberOfBitsInPlaintext + 7) >> 3;
|
|
|
|
|
int32 PaddedSize = (NumberOfBytesInPlaintext + 15) / 16 * 16;
|
|
|
|
|
TArray<uint8> CipherText;
|
|
|
|
|
TArray<uint8> PlainText;
|
|
|
|
|
|
|
|
|
|
CipherText.AddUninitialized(PaddedSize);
|
|
|
|
|
PlainText.AddUninitialized(PaddedSize);
|
|
|
|
|
|
|
|
|
|
Packet.Serialize(CipherText.GetData(), PaddedSize);
|
|
|
|
|
|
|
|
|
|
if (!Packet.IsError())
|
|
|
|
|
{
|
|
|
|
|
SymmetricDecrypt.ProcessData(PlainText.GetData(), CipherText.GetData(), PaddedSize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// @todo: Could do with optimization
|
|
|
|
|
FBitReader Copy(PlainText.GetData(), NumberOfBitsInPlaintext);
|
|
|
|
|
|
|
|
|
|
Packet = Copy;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Error, TEXT("AES: Error serializing PlainText."));
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Packet.SetError();
|
|
|
|
|
|
|
|
|
|
UE_LOG(PacketHandlerLog, Error, TEXT("AES: Specified PlainText size exceeds MAX_COMPRESSED_PACKET_SIZE."));
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Error, TEXT("AES: Error serializing incoming packet."));
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
IncomingHandshake(Packet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::IncomingHandshake(FBitReader& Packet)
|
|
|
|
|
{
|
|
|
|
|
bool bHandledPacket = true;
|
|
|
|
|
|
|
|
|
|
if (Handler->Mode == Handler::Mode::Server)
|
|
|
|
|
{
|
|
|
|
|
if (State == ERSAKeyAESEncryptionHandler::State::SentKey)
|
|
|
|
|
{
|
|
|
|
|
FPacketAudit::CheckStage(TEXT("SessionKeyExchangeEncrypt"), Packet);
|
|
|
|
|
|
|
|
|
|
AsymmetricDecryptPacket(Packet);
|
|
|
|
|
|
|
|
|
|
FPacketAudit::CheckStage(TEXT("SessionKeyExchangeDecrypt"), Packet);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32 KeySizeBytes = SessionKeySize / 8;
|
|
|
|
|
TArray<uint8> InitializationVector;
|
|
|
|
|
|
|
|
|
|
InitializationVector.SetNumUninitialized(AES_BLOCK_SIZE);
|
|
|
|
|
SessionKey.SetNumUninitialized(KeySizeBytes);
|
|
|
|
|
|
|
|
|
|
Packet.Serialize(InitializationVector.GetData(), AES_BLOCK_SIZE);
|
|
|
|
|
Packet.Serialize(SessionKey.GetData(), KeySizeBytes);
|
|
|
|
|
|
|
|
|
|
if (!Packet.IsError())
|
|
|
|
|
{
|
|
|
|
|
SymmetricEncrypt.SetKeyWithIV(SessionKey.GetData(), KeySizeBytes, InitializationVector.GetData(), AES_BLOCK_SIZE);
|
|
|
|
|
SymmetricDecrypt.SetKeyWithIV(SessionKey.GetData(), KeySizeBytes, InitializationVector.GetData(), AES_BLOCK_SIZE);
|
|
|
|
|
|
|
|
|
|
// Now mark as initialized
|
|
|
|
|
SetState(ERSAKeyAESEncryptionHandler::State::Initialized);
|
|
|
|
|
Initialized();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Error, TEXT("RSA: Failed to initialize symmetric encryption."));
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bHandledPacket = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (Handler->Mode == Handler::Mode::Client)
|
|
|
|
|
{
|
|
|
|
|
if (State == ERSAKeyAESEncryptionHandler::State::UnInitialized)
|
|
|
|
|
{
|
|
|
|
|
FPacketAudit::CheckStage(TEXT("RSAHandshake"), Packet);
|
|
|
|
|
|
|
|
|
|
UnPackAsymmetricKey(Packet);
|
|
|
|
|
|
|
|
|
|
// Generate/send the session key and initialization vector, and setup the symmetric encryption locally
|
|
|
|
|
if (!Packet.IsError())
|
|
|
|
|
{
|
|
|
|
|
check(AES_BLOCK_SIZE == CryptoPP::AES::BLOCKSIZE);
|
|
|
|
|
check((SessionKeySize % 8) == 0);
|
|
|
|
|
|
|
|
|
|
CryptoPP::AutoSeededRandomPool SessionRng;
|
|
|
|
|
TArray<uint8> InitializationVector;
|
|
|
|
|
uint32 KeySizeBytes = SessionKeySize / 8;
|
|
|
|
|
|
|
|
|
|
SessionKey.SetNumUninitialized(KeySizeBytes);
|
|
|
|
|
InitializationVector.SetNumUninitialized(AES_BLOCK_SIZE);
|
|
|
|
|
|
|
|
|
|
SessionRng.GenerateBlock(SessionKey.GetData(), KeySizeBytes);
|
|
|
|
|
SessionRng.GenerateBlock(InitializationVector.GetData(), AES_BLOCK_SIZE);
|
|
|
|
|
|
|
|
|
|
SymmetricEncrypt.SetKeyWithIV(SessionKey.GetData(), KeySizeBytes, InitializationVector.GetData(), AES_BLOCK_SIZE);
|
|
|
|
|
SymmetricDecrypt.SetKeyWithIV(SessionKey.GetData(), KeySizeBytes, InitializationVector.GetData(), AES_BLOCK_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Now send the initialization vector and session key
|
|
|
|
|
FBitWriter OutPacket((AES_BLOCK_SIZE + KeySizeBytes) * 8, true);
|
2018-09-25 10:11:35 -04:00
|
|
|
FOutPacketTraits Traits;
|
Copying //UE4/Dev-Networking to //UE4/Dev-Main (Source: //UE4/Dev-Networking @ 3495493)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3302759 on 2017/02/14 by John.Pollard
Remove invalid replay samples that can occur due to oversampling (sampling at higher rate than physics is being ticked)
Change 3306072 on 2017/02/16 by John.Barrett
Minor NetcodeUnitTest updates/fixes.
Improved assignment for some types, using FVMReflection - added assignment to enum by name.
Change 3322165 on 2017/02/24 by John.Barrett
Fixed issue where Steam would block unit tests. #JIRA UENET-537
Change 3323917 on 2017/02/27 by John.Barrett
Added better unit test log file management. #JIRA UENET-535
Unit test logs are now stored in subfolders in the game log folder, with one main folder for the current UE4 session, and one subfolder for every unit test run during that session.
Logs are purged occasionally, in line with how the main game logs are purged.
Change 3326307 on 2017/02/28 by John.Pollard
Remove unused cvar
Change 3327907 on 2017/03/01 by John.Barrett
Merged some old NetcodeUnitTest debug features:
- Added command for bit-based log dumping of data (for debugging bit-based netcode)
- Added exported function, for allowing access to console commands, in modules which don't import Engine
Change 3332710 on 2017/03/05 by John.Barrett
Updated unit test flags to expect a disconnect when expecting a server crash.
Change 3332715 on 2017/03/05 by John.Barrett
Wrapped all CreateChannelBunch pointers with a nullptr check (used to not be required).
Replaced old/duplicate unit test code (using CreateChannelBunch) for marking 'exploit failure', with the current centralized function calls.
#JIRA UENET-539
Change 3336258 on 2017/03/07 by John.Pollard
Add more info to history overflow logging
Change 3336259 on 2017/03/07 by John.Pollard
Don't pause replication for replay connections
Change 3341288 on 2017/03/10 by John.Barrett
Fixed invalid access to GLog during game shutdown. #JIRA UE-42394
Change 3341736 on 2017/03/10 by John.Pollard
Get reliability packet handler working again (but still disabled by default)
Change 3349298 on 2017/03/16 by John.Barrett
Fixed issues/potential-issues with the timing of global variable destruction, based on Graeme Thornton's fix. #JIRA UE-42394
Change 3349393 on 2017/03/16 by John.Pollard
Reliability handler cleanup
Change 3350029 on 2017/03/16 by John.Barrett
Updated PacketHandler to support an optional handshaking stage for HandlerComponents, where each handshake must execute sequentially starting at the component closest to the socket.
Change 3350030 on 2017/03/16 by John.Barrett
Updated Asymetric Encryption to support updated PacketHandler system, to perform a key handshake that is compatible with other HandlerComponent's, and fixed some serialization security issues by setting proper limits on values.
Change 3350032 on 2017/03/16 by John.Barrett
Minor corrections to variable types and constructor initializer lists, for the rest of the encryption code.
Change 3355536 on 2017/03/20 by John.Barrett
Added new PacketAudit debug feature, which uses inter-process-communication, to audit the integrity of incoming/outgoing packets at various stages of serialization, between a client and server.
This is critically useful for low level netcode development, particularly with the PacketHandler.
See PacketAudit.h for more information.
Change 3355570 on 2017/03/20 by John.Barrett
Added a small number packet auditing checks to key areas of low level netcode.
Change 3355584 on 2017/03/20 by John.Barrett
Updated ReliabilityHandlerComponent, to support packet reliability during the PacketHandler handshaking stage, and fixed ReliabilityHandlerComponent serializing based on a packets byte size, rather than bit size.
Change 3373389 on 2017/03/30 by John.Barrett
Added check for HandlerComponent's that require reliability.
Change 3373390 on 2017/03/30 by John.Barrett
Added TLS-like encryption handler component, which exchanges a secret key using asymmetric encryption (RSA), and implements symmetric encryption using that key (AES).
Based on RSA encryption component, and John Pollard's AES changes.
Enable in *Engine.ini, using:
[PacketHandlerComponents]
Components=RSAKeyAESEncryption
bEnableReliability=true
Change 3394518 on 2017/04/14 by Ryan.Gerleve
Fix memory leak in FRepChangelistState: added destructor that properly destroys the properties in the shadow state buffer.
Change 3432955 on 2017/05/10 by John.Barrett
Randomized the initial packet sequence numbers for UNetConnection's and for reliable packets - using the stateless handshake cookie.
Also added hooks to determine when PacketHandler level handshaking has completed, so that the initial connection packets can be delayed until this stage (required now, in order to exchange the sequence numbers first).
Change 3464528 on 2017/05/29 by John.Barrett
Fixed connection failure during unreliable network conditions, caused by a bad interaction between the stateless handshake and sequence initialization code.
Added a new 'ack' stage to the stateless handshake, to ensure the client/server sequence is properly synchronised.
Expanded the timeout/retry handling for the stateless handshake, so it is more robust, and fixed some bugs in this code.
Change 3464537 on 2017/05/29 by John.Barrett
Fixed an incompatibility between the asymmetric encryption, and the new PacketHandler handshake code.
Change 3464543 on 2017/05/29 by John.Barrett
Updated CryptoPP to 5.6.5.
Change 3467529 on 2017/05/31 by Jon.Nabozny
Add comments to FPacketSimulationSettings vars.
Change 3469584 on 2017/06/01 by Ryan.Gerleve
Log bunch ChSequence on reliable channel open along with other info.
Change 3471329 on 2017/06/02 by John.Barrett
Fixed PacketHandlerLog type not being exported.
Change 3471875 on 2017/06/02 by John.Barrett
Fixed code that was trying to send NetConnection packets from the server to the client, too early - and tidied up related checks.
#JIRA UE-45637
Change 3473030 on 2017/06/04 by John.Barrett
Fixed replay incomaptibility with recent sequence/handshake changes.
Change 3476313 on 2017/06/06 by Ryan.Gerleve
Add initial reliable sequence numbers to the log in UNetConnection::InitSequence.
Change 3478649 on 2017/06/07 by Ryan.Gerleve
Add additional logging for the case where a channel open command is received by a channel that's already opened locally.
Change 3482926 on 2017/06/09 by John.Barrett
First pass at Minimal Client refactor for NetcodeUnitTest - split basic/minimal client code out of ClientUnitTest, into its own class - while preserving existing ClientUnitTest interface.
This will allow multiple minimal clients per unit test, where only one could be used before (necessary for games that require a beacon + game connection).
Added reflection support for weak UObject properties.
Added MCP requirements flag for unit tests.
Process pipe reading tweaks, to avoid UI freezes.
Change 3485179 on 2017/06/12 by Ryan.Gerleve
Add backwards-compatibility macros for random initial packet sequence changes so that game plugins can check them.
Change 3489040 on 2017/06/14 by John.Barrett
Removed OnlineSubsystem dependencies.
[CL 3495525 by Ryan Gerleve in Main branch]
2017-06-16 14:10:35 -04:00
|
|
|
|
|
|
|
|
OutPacket.Serialize(InitializationVector.GetData(), AES_BLOCK_SIZE);
|
|
|
|
|
OutPacket.Serialize(SessionKey.GetData(), KeySizeBytes);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FPacketAudit::AddStage(TEXT("SessionKeyExchangeDecrypt"), OutPacket);
|
|
|
|
|
|
|
|
|
|
AsymmetricEncryptPacket(OutPacket);
|
|
|
|
|
|
|
|
|
|
FPacketAudit::AddStage(TEXT("SessionKeyExchangeEncrypt"), OutPacket);
|
|
|
|
|
|
2018-09-25 10:11:35 -04:00
|
|
|
Handler->SendHandlerPacket(this, OutPacket, Traits);
|
Copying //UE4/Dev-Networking to //UE4/Dev-Main (Source: //UE4/Dev-Networking @ 3495493)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3302759 on 2017/02/14 by John.Pollard
Remove invalid replay samples that can occur due to oversampling (sampling at higher rate than physics is being ticked)
Change 3306072 on 2017/02/16 by John.Barrett
Minor NetcodeUnitTest updates/fixes.
Improved assignment for some types, using FVMReflection - added assignment to enum by name.
Change 3322165 on 2017/02/24 by John.Barrett
Fixed issue where Steam would block unit tests. #JIRA UENET-537
Change 3323917 on 2017/02/27 by John.Barrett
Added better unit test log file management. #JIRA UENET-535
Unit test logs are now stored in subfolders in the game log folder, with one main folder for the current UE4 session, and one subfolder for every unit test run during that session.
Logs are purged occasionally, in line with how the main game logs are purged.
Change 3326307 on 2017/02/28 by John.Pollard
Remove unused cvar
Change 3327907 on 2017/03/01 by John.Barrett
Merged some old NetcodeUnitTest debug features:
- Added command for bit-based log dumping of data (for debugging bit-based netcode)
- Added exported function, for allowing access to console commands, in modules which don't import Engine
Change 3332710 on 2017/03/05 by John.Barrett
Updated unit test flags to expect a disconnect when expecting a server crash.
Change 3332715 on 2017/03/05 by John.Barrett
Wrapped all CreateChannelBunch pointers with a nullptr check (used to not be required).
Replaced old/duplicate unit test code (using CreateChannelBunch) for marking 'exploit failure', with the current centralized function calls.
#JIRA UENET-539
Change 3336258 on 2017/03/07 by John.Pollard
Add more info to history overflow logging
Change 3336259 on 2017/03/07 by John.Pollard
Don't pause replication for replay connections
Change 3341288 on 2017/03/10 by John.Barrett
Fixed invalid access to GLog during game shutdown. #JIRA UE-42394
Change 3341736 on 2017/03/10 by John.Pollard
Get reliability packet handler working again (but still disabled by default)
Change 3349298 on 2017/03/16 by John.Barrett
Fixed issues/potential-issues with the timing of global variable destruction, based on Graeme Thornton's fix. #JIRA UE-42394
Change 3349393 on 2017/03/16 by John.Pollard
Reliability handler cleanup
Change 3350029 on 2017/03/16 by John.Barrett
Updated PacketHandler to support an optional handshaking stage for HandlerComponents, where each handshake must execute sequentially starting at the component closest to the socket.
Change 3350030 on 2017/03/16 by John.Barrett
Updated Asymetric Encryption to support updated PacketHandler system, to perform a key handshake that is compatible with other HandlerComponent's, and fixed some serialization security issues by setting proper limits on values.
Change 3350032 on 2017/03/16 by John.Barrett
Minor corrections to variable types and constructor initializer lists, for the rest of the encryption code.
Change 3355536 on 2017/03/20 by John.Barrett
Added new PacketAudit debug feature, which uses inter-process-communication, to audit the integrity of incoming/outgoing packets at various stages of serialization, between a client and server.
This is critically useful for low level netcode development, particularly with the PacketHandler.
See PacketAudit.h for more information.
Change 3355570 on 2017/03/20 by John.Barrett
Added a small number packet auditing checks to key areas of low level netcode.
Change 3355584 on 2017/03/20 by John.Barrett
Updated ReliabilityHandlerComponent, to support packet reliability during the PacketHandler handshaking stage, and fixed ReliabilityHandlerComponent serializing based on a packets byte size, rather than bit size.
Change 3373389 on 2017/03/30 by John.Barrett
Added check for HandlerComponent's that require reliability.
Change 3373390 on 2017/03/30 by John.Barrett
Added TLS-like encryption handler component, which exchanges a secret key using asymmetric encryption (RSA), and implements symmetric encryption using that key (AES).
Based on RSA encryption component, and John Pollard's AES changes.
Enable in *Engine.ini, using:
[PacketHandlerComponents]
Components=RSAKeyAESEncryption
bEnableReliability=true
Change 3394518 on 2017/04/14 by Ryan.Gerleve
Fix memory leak in FRepChangelistState: added destructor that properly destroys the properties in the shadow state buffer.
Change 3432955 on 2017/05/10 by John.Barrett
Randomized the initial packet sequence numbers for UNetConnection's and for reliable packets - using the stateless handshake cookie.
Also added hooks to determine when PacketHandler level handshaking has completed, so that the initial connection packets can be delayed until this stage (required now, in order to exchange the sequence numbers first).
Change 3464528 on 2017/05/29 by John.Barrett
Fixed connection failure during unreliable network conditions, caused by a bad interaction between the stateless handshake and sequence initialization code.
Added a new 'ack' stage to the stateless handshake, to ensure the client/server sequence is properly synchronised.
Expanded the timeout/retry handling for the stateless handshake, so it is more robust, and fixed some bugs in this code.
Change 3464537 on 2017/05/29 by John.Barrett
Fixed an incompatibility between the asymmetric encryption, and the new PacketHandler handshake code.
Change 3464543 on 2017/05/29 by John.Barrett
Updated CryptoPP to 5.6.5.
Change 3467529 on 2017/05/31 by Jon.Nabozny
Add comments to FPacketSimulationSettings vars.
Change 3469584 on 2017/06/01 by Ryan.Gerleve
Log bunch ChSequence on reliable channel open along with other info.
Change 3471329 on 2017/06/02 by John.Barrett
Fixed PacketHandlerLog type not being exported.
Change 3471875 on 2017/06/02 by John.Barrett
Fixed code that was trying to send NetConnection packets from the server to the client, too early - and tidied up related checks.
#JIRA UE-45637
Change 3473030 on 2017/06/04 by John.Barrett
Fixed replay incomaptibility with recent sequence/handshake changes.
Change 3476313 on 2017/06/06 by Ryan.Gerleve
Add initial reliable sequence numbers to the log in UNetConnection::InitSequence.
Change 3478649 on 2017/06/07 by Ryan.Gerleve
Add additional logging for the case where a channel open command is received by a channel that's already opened locally.
Change 3482926 on 2017/06/09 by John.Barrett
First pass at Minimal Client refactor for NetcodeUnitTest - split basic/minimal client code out of ClientUnitTest, into its own class - while preserving existing ClientUnitTest interface.
This will allow multiple minimal clients per unit test, where only one could be used before (necessary for games that require a beacon + game connection).
Added reflection support for weak UObject properties.
Added MCP requirements flag for unit tests.
Process pipe reading tweaks, to avoid UI freezes.
Change 3485179 on 2017/06/12 by Ryan.Gerleve
Add backwards-compatibility macros for random initial packet sequence changes so that game plugins can check them.
Change 3489040 on 2017/06/14 by John.Barrett
Removed OnlineSubsystem dependencies.
[CL 3495525 by Ryan Gerleve in Main branch]
2017-06-16 14:10:35 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// Now mark as initialized
|
|
|
|
|
SetState(ERSAKeyAESEncryptionHandler::State::Initialized);
|
|
|
|
|
Initialized();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Error, TEXT("RSA: Error unpacking the asymmetric key, can't complete handshake."));
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bHandledPacket = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!bHandledPacket)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Warning, TEXT("RSAEncryptionHandlerComponent: Got incoming packet when not yet initialized."));
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
Packet.SetError();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-25 10:11:35 -04:00
|
|
|
int32 RSAKeyAESEncryptionHandlerComponent::GetReservedPacketBits() const
|
Copying //UE4/Dev-Networking to //UE4/Dev-Main (Source: //UE4/Dev-Networking @ 3495493)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3302759 on 2017/02/14 by John.Pollard
Remove invalid replay samples that can occur due to oversampling (sampling at higher rate than physics is being ticked)
Change 3306072 on 2017/02/16 by John.Barrett
Minor NetcodeUnitTest updates/fixes.
Improved assignment for some types, using FVMReflection - added assignment to enum by name.
Change 3322165 on 2017/02/24 by John.Barrett
Fixed issue where Steam would block unit tests. #JIRA UENET-537
Change 3323917 on 2017/02/27 by John.Barrett
Added better unit test log file management. #JIRA UENET-535
Unit test logs are now stored in subfolders in the game log folder, with one main folder for the current UE4 session, and one subfolder for every unit test run during that session.
Logs are purged occasionally, in line with how the main game logs are purged.
Change 3326307 on 2017/02/28 by John.Pollard
Remove unused cvar
Change 3327907 on 2017/03/01 by John.Barrett
Merged some old NetcodeUnitTest debug features:
- Added command for bit-based log dumping of data (for debugging bit-based netcode)
- Added exported function, for allowing access to console commands, in modules which don't import Engine
Change 3332710 on 2017/03/05 by John.Barrett
Updated unit test flags to expect a disconnect when expecting a server crash.
Change 3332715 on 2017/03/05 by John.Barrett
Wrapped all CreateChannelBunch pointers with a nullptr check (used to not be required).
Replaced old/duplicate unit test code (using CreateChannelBunch) for marking 'exploit failure', with the current centralized function calls.
#JIRA UENET-539
Change 3336258 on 2017/03/07 by John.Pollard
Add more info to history overflow logging
Change 3336259 on 2017/03/07 by John.Pollard
Don't pause replication for replay connections
Change 3341288 on 2017/03/10 by John.Barrett
Fixed invalid access to GLog during game shutdown. #JIRA UE-42394
Change 3341736 on 2017/03/10 by John.Pollard
Get reliability packet handler working again (but still disabled by default)
Change 3349298 on 2017/03/16 by John.Barrett
Fixed issues/potential-issues with the timing of global variable destruction, based on Graeme Thornton's fix. #JIRA UE-42394
Change 3349393 on 2017/03/16 by John.Pollard
Reliability handler cleanup
Change 3350029 on 2017/03/16 by John.Barrett
Updated PacketHandler to support an optional handshaking stage for HandlerComponents, where each handshake must execute sequentially starting at the component closest to the socket.
Change 3350030 on 2017/03/16 by John.Barrett
Updated Asymetric Encryption to support updated PacketHandler system, to perform a key handshake that is compatible with other HandlerComponent's, and fixed some serialization security issues by setting proper limits on values.
Change 3350032 on 2017/03/16 by John.Barrett
Minor corrections to variable types and constructor initializer lists, for the rest of the encryption code.
Change 3355536 on 2017/03/20 by John.Barrett
Added new PacketAudit debug feature, which uses inter-process-communication, to audit the integrity of incoming/outgoing packets at various stages of serialization, between a client and server.
This is critically useful for low level netcode development, particularly with the PacketHandler.
See PacketAudit.h for more information.
Change 3355570 on 2017/03/20 by John.Barrett
Added a small number packet auditing checks to key areas of low level netcode.
Change 3355584 on 2017/03/20 by John.Barrett
Updated ReliabilityHandlerComponent, to support packet reliability during the PacketHandler handshaking stage, and fixed ReliabilityHandlerComponent serializing based on a packets byte size, rather than bit size.
Change 3373389 on 2017/03/30 by John.Barrett
Added check for HandlerComponent's that require reliability.
Change 3373390 on 2017/03/30 by John.Barrett
Added TLS-like encryption handler component, which exchanges a secret key using asymmetric encryption (RSA), and implements symmetric encryption using that key (AES).
Based on RSA encryption component, and John Pollard's AES changes.
Enable in *Engine.ini, using:
[PacketHandlerComponents]
Components=RSAKeyAESEncryption
bEnableReliability=true
Change 3394518 on 2017/04/14 by Ryan.Gerleve
Fix memory leak in FRepChangelistState: added destructor that properly destroys the properties in the shadow state buffer.
Change 3432955 on 2017/05/10 by John.Barrett
Randomized the initial packet sequence numbers for UNetConnection's and for reliable packets - using the stateless handshake cookie.
Also added hooks to determine when PacketHandler level handshaking has completed, so that the initial connection packets can be delayed until this stage (required now, in order to exchange the sequence numbers first).
Change 3464528 on 2017/05/29 by John.Barrett
Fixed connection failure during unreliable network conditions, caused by a bad interaction between the stateless handshake and sequence initialization code.
Added a new 'ack' stage to the stateless handshake, to ensure the client/server sequence is properly synchronised.
Expanded the timeout/retry handling for the stateless handshake, so it is more robust, and fixed some bugs in this code.
Change 3464537 on 2017/05/29 by John.Barrett
Fixed an incompatibility between the asymmetric encryption, and the new PacketHandler handshake code.
Change 3464543 on 2017/05/29 by John.Barrett
Updated CryptoPP to 5.6.5.
Change 3467529 on 2017/05/31 by Jon.Nabozny
Add comments to FPacketSimulationSettings vars.
Change 3469584 on 2017/06/01 by Ryan.Gerleve
Log bunch ChSequence on reliable channel open along with other info.
Change 3471329 on 2017/06/02 by John.Barrett
Fixed PacketHandlerLog type not being exported.
Change 3471875 on 2017/06/02 by John.Barrett
Fixed code that was trying to send NetConnection packets from the server to the client, too early - and tidied up related checks.
#JIRA UE-45637
Change 3473030 on 2017/06/04 by John.Barrett
Fixed replay incomaptibility with recent sequence/handshake changes.
Change 3476313 on 2017/06/06 by Ryan.Gerleve
Add initial reliable sequence numbers to the log in UNetConnection::InitSequence.
Change 3478649 on 2017/06/07 by Ryan.Gerleve
Add additional logging for the case where a channel open command is received by a channel that's already opened locally.
Change 3482926 on 2017/06/09 by John.Barrett
First pass at Minimal Client refactor for NetcodeUnitTest - split basic/minimal client code out of ClientUnitTest, into its own class - while preserving existing ClientUnitTest interface.
This will allow multiple minimal clients per unit test, where only one could be used before (necessary for games that require a beacon + game connection).
Added reflection support for weak UObject properties.
Added MCP requirements flag for unit tests.
Process pipe reading tweaks, to avoid UI freezes.
Change 3485179 on 2017/06/12 by Ryan.Gerleve
Add backwards-compatibility macros for random initial packet sequence changes so that game plugins can check them.
Change 3489040 on 2017/06/14 by John.Barrett
Removed OnlineSubsystem dependencies.
[CL 3495525 by Ryan Gerleve in Main branch]
2017-06-16 14:10:35 -04:00
|
|
|
{
|
|
|
|
|
int32 ReturnVal = 0;
|
|
|
|
|
|
|
|
|
|
// Count the size of the value, representing the packet size in bits
|
|
|
|
|
FBitWriter MeasureAr(0, true);
|
|
|
|
|
uint32 TestVal = MAX_COMPRESSED_PACKET_SIZE - 1;
|
|
|
|
|
|
|
|
|
|
MeasureAr.SerializeInt(TestVal, MAX_COMPRESSED_PACKET_SIZE);
|
|
|
|
|
|
|
|
|
|
check(!MeasureAr.IsError());
|
|
|
|
|
|
|
|
|
|
ReturnVal += MeasureAr.GetNumBits();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Count the worst case amount of padding that may be added to a packet
|
|
|
|
|
ReturnVal += (16 * 8) - 1;
|
|
|
|
|
|
|
|
|
|
return ReturnVal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::PackAsymmetricKey(FBitWriter& Packet)
|
|
|
|
|
{
|
|
|
|
|
FBitWriter Local;
|
|
|
|
|
Local.AllowAppend(true);
|
|
|
|
|
Local.SetAllowResize(true);
|
|
|
|
|
|
|
|
|
|
// Save remote public key information
|
|
|
|
|
TArray<uint8> ModulusArray;
|
|
|
|
|
TArray<uint8> ExponentArray;
|
|
|
|
|
|
|
|
|
|
SavePublicKeyModulus(ModulusArray);
|
|
|
|
|
SavePublicKeyExponent(ExponentArray);
|
|
|
|
|
|
|
|
|
|
if ((ModulusArray.Num() * 8u) > AsymmetricKeySize || ModulusArray.Num() == 0)
|
|
|
|
|
{
|
|
|
|
|
LowLevelFatalError(TEXT("Modulus size '%i bits' must be greater than zero, and must not exceed key size '%i'"),
|
|
|
|
|
(ModulusArray.Num() * 8), AsymmetricKeySize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((ExponentArray.Num() * 8) > MAX_EXPONENT_BITS || ExponentArray.Num() == 0)
|
|
|
|
|
{
|
|
|
|
|
LowLevelFatalError(TEXT("Exponent size '%i bits' must be greater than zero, and must not exceed MAX_EXPONENT_BITS"),
|
|
|
|
|
(ExponentArray.Num() * 8));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const uint32 MaxModulusNum = (AsymmetricKeySize + 7) >> 3;
|
|
|
|
|
const uint32 MaxExponentNum = (MAX_EXPONENT_BITS + 7) >> 3;
|
|
|
|
|
|
|
|
|
|
// Decrement by one, to allow serialization of #Num == Max#Num
|
|
|
|
|
uint32 ModulusSerializeNum = ModulusArray.Num() - 1;
|
|
|
|
|
uint32 ExponentSerializeNum = ExponentArray.Num() - 1;
|
|
|
|
|
|
|
|
|
|
Local.SerializeInt(ModulusSerializeNum, MaxModulusNum);
|
|
|
|
|
Local.Serialize(ModulusArray.GetData(), ModulusArray.Num());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Local.SerializeInt(ExponentSerializeNum, MaxExponentNum);
|
|
|
|
|
Local.Serialize(ExponentArray.GetData(), ExponentArray.Num());
|
|
|
|
|
|
|
|
|
|
Local.Serialize(Packet.GetData(), Packet.GetNumBytes());
|
|
|
|
|
|
|
|
|
|
Packet = Local;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::UnPackAsymmetricKey(FBitReader& Packet)
|
|
|
|
|
{
|
|
|
|
|
// Save remote public key
|
|
|
|
|
TArray<uint8> ModulusArray;
|
|
|
|
|
TArray<uint8> ExponentArray;
|
|
|
|
|
const uint32 MaxModulusNum = (AsymmetricKeySize + 7) >> 3;
|
|
|
|
|
const uint32 MaxExponentNum = (MAX_EXPONENT_BITS + 7) >> 3;
|
|
|
|
|
|
|
|
|
|
uint32 ModulusNum = 0;
|
|
|
|
|
|
|
|
|
|
Packet.SerializeInt(ModulusNum, MaxModulusNum);
|
|
|
|
|
|
|
|
|
|
ModulusNum++;
|
|
|
|
|
|
|
|
|
|
if ((ModulusNum * 8) > AsymmetricKeySize)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Warning, TEXT("RSA: Modulus size '%i bits' should not exceed key size '%i'"),
|
|
|
|
|
(ModulusNum * 8), AsymmetricKeySize);
|
|
|
|
|
|
|
|
|
|
Packet.SetError();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!Packet.IsError())
|
|
|
|
|
{
|
|
|
|
|
uint32 ExponentNum = 0;
|
|
|
|
|
|
|
|
|
|
ModulusArray.SetNumUninitialized(ModulusNum);
|
|
|
|
|
|
|
|
|
|
Packet.Serialize(ModulusArray.GetData(), ModulusNum);
|
|
|
|
|
Packet.SerializeInt(ExponentNum, MaxExponentNum);
|
|
|
|
|
|
|
|
|
|
if (!Packet.IsError())
|
|
|
|
|
{
|
|
|
|
|
ExponentNum++;
|
|
|
|
|
|
|
|
|
|
if ((ExponentNum * 8) <= MAX_EXPONENT_BITS)
|
|
|
|
|
{
|
|
|
|
|
ExponentArray.SetNumUninitialized(ExponentNum);
|
|
|
|
|
Packet.Serialize(ExponentArray.GetData(), ExponentNum);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Warning, TEXT("RSA: Exponent size '%i bits' should not exceed MAX_EXPONENT_BITS"),
|
|
|
|
|
(ExponentNum * 8));
|
|
|
|
|
|
|
|
|
|
Packet.SetError();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!Packet.IsError())
|
|
|
|
|
{
|
|
|
|
|
// Make sure the packet has no remaining data now
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(Packet.GetBitsLeft() == 0);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
CryptoPP::Integer Modulus;
|
|
|
|
|
CryptoPP::Integer Exponent;
|
|
|
|
|
|
|
|
|
|
for (int32 i = 0; i < ModulusArray.Num(); ++i)
|
|
|
|
|
{
|
|
|
|
|
Modulus.SetByte(i, ModulusArray[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int32 i = 0; i < ExponentArray.Num(); ++i)
|
|
|
|
|
{
|
|
|
|
|
Exponent.SetByte(i, ExponentArray[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PublicKey.SetModulus(Modulus);
|
|
|
|
|
PublicKey.SetPublicExponent(Exponent);
|
|
|
|
|
|
|
|
|
|
AsymmetricEncrypt = CryptoPP::RSAES_OAEP_SHA_Encryptor(PublicKey);
|
|
|
|
|
AsymmetricKeyMaxPlaintextLength = static_cast<uint32>(AsymmetricEncrypt.FixedMaxPlaintextLength());
|
|
|
|
|
AsymmetricKeyFixedCiphertextLength = static_cast<uint32>(AsymmetricEncrypt.FixedCiphertextLength());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::AsymmetricEncryptPacket(FBitWriter& Packet)
|
|
|
|
|
{
|
|
|
|
|
// Serialize size of plain text data
|
|
|
|
|
uint32 NumberOfBytesInPlaintext = static_cast<uint32>(Packet.GetNumBytes());
|
|
|
|
|
TArray<uint8> PlainText;
|
|
|
|
|
|
|
|
|
|
PlainText.AddUninitialized(NumberOfBytesInPlaintext);
|
|
|
|
|
|
|
|
|
|
FMemory::Memcpy(PlainText.GetData(), Packet.GetData(), NumberOfBytesInPlaintext);
|
|
|
|
|
|
|
|
|
|
Packet.Reset();
|
|
|
|
|
|
|
|
|
|
if (NumberOfBytesInPlaintext == 0 || NumberOfBytesInPlaintext > AsymmetricKeyMaxPlaintextLength)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Warning, TEXT("RSA: Encryption failed due to invalid plain text size '%i/%i'."),
|
|
|
|
|
NumberOfBytesInPlaintext, AsymmetricKeyMaxPlaintextLength);
|
|
|
|
|
|
|
|
|
|
Packet.SetError();
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TArray<uint8> CipherText;
|
|
|
|
|
|
|
|
|
|
CipherText.SetNumUninitialized(AsymmetricKeyFixedCiphertextLength);
|
|
|
|
|
AsymmetricEncrypt.Encrypt(AsymmetricRng, PlainText.GetData(), PlainText.Num(), CipherText.GetData());
|
|
|
|
|
|
|
|
|
|
NumberOfBytesInPlaintext--;
|
|
|
|
|
Packet.SerializeInt(NumberOfBytesInPlaintext, AsymmetricKeyMaxPlaintextLength);
|
|
|
|
|
|
|
|
|
|
Packet.Serialize(CipherText.GetData(), CipherText.Num());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::AsymmetricDecryptPacket(FBitReader& Packet)
|
|
|
|
|
{
|
|
|
|
|
// Serialize size of plain text data
|
|
|
|
|
uint32 NumberOfBytesInPlaintext;
|
|
|
|
|
|
|
|
|
|
Packet.SerializeInt(NumberOfBytesInPlaintext, AsymmetricKeyMaxPlaintextLength);
|
|
|
|
|
NumberOfBytesInPlaintext++;
|
|
|
|
|
|
|
|
|
|
if (NumberOfBytesInPlaintext == 0 || NumberOfBytesInPlaintext > AsymmetricKeyMaxPlaintextLength)
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(PacketHandlerLog, Warning, TEXT("RSA: Decryption failed due to invalid cipher text size '%i/%i'."),
|
|
|
|
|
NumberOfBytesInPlaintext, AsymmetricKeyMaxPlaintextLength);
|
|
|
|
|
|
|
|
|
|
Packet.SetError();
|
|
|
|
|
|
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
|
|
|
check(false);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy byte stream to PlainText from Packet; not including the NumOfBytesPT field
|
|
|
|
|
if (!Packet.IsError())
|
|
|
|
|
{
|
|
|
|
|
// @todo #JohnB: This is not bit-safe (but should not matter, since this code is only used during handshake, but still...)
|
|
|
|
|
TArray<uint8> PlainText;
|
|
|
|
|
int32 StartPos = Packet.GetPosBits() / 8;
|
|
|
|
|
|
|
|
|
|
PlainText.SetNumUninitialized(AsymmetricKeyMaxPlaintextLength);
|
|
|
|
|
AsymmetricDecrypt.Decrypt(AsymmetricRng, (Packet.GetData() + StartPos), (Packet.GetNumBytes() - StartPos), PlainText.GetData());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// @todo #JohnB: Optimize this
|
|
|
|
|
FBitReader Copy(PlainText.GetData(), NumberOfBytesInPlaintext * 8);
|
|
|
|
|
Packet = Copy;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::SavePublicKeyModulus(TArray<uint8>& OutModulus)
|
|
|
|
|
{
|
|
|
|
|
uint32 ModulusSize = static_cast<uint32>(PublicKey.GetModulus().ByteCount());
|
|
|
|
|
|
|
|
|
|
CryptoPP::Integer Modulus = PublicKey.GetModulus();
|
|
|
|
|
|
|
|
|
|
for (uint32 i = 0; i < ModulusSize; ++i)
|
|
|
|
|
{
|
|
|
|
|
OutModulus.Add(Modulus.GetByte(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RSAKeyAESEncryptionHandlerComponent::SavePublicKeyExponent(TArray<uint8>& OutExponent)
|
|
|
|
|
{
|
|
|
|
|
uint32 ExponentSize = static_cast<uint32>(PublicKey.GetPublicExponent().ByteCount());
|
|
|
|
|
|
|
|
|
|
CryptoPP::Integer Exponent = PublicKey.GetPublicExponent();
|
|
|
|
|
|
|
|
|
|
for (uint32 i = 0; i < ExponentSize; ++i)
|
|
|
|
|
{
|
|
|
|
|
OutExponent.Add(Exponent.GetByte(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// MODULE INTERFACE
|
|
|
|
|
TSharedPtr<HandlerComponent> FRSAKeyAESEncryptionModuleInterface::CreateComponentInstance(FString& Options)
|
|
|
|
|
{
|
|
|
|
|
return MakeShareable(new RSAKeyAESEncryptionHandlerComponent());
|
|
|
|
|
}
|