Updating DTLS packet handler to respect SSL platform availability

#jira UE-179371
#preflight 6407dcde5515f4f57b645c5e
#rb ryan.gerleve
#lockdown julien.marchand

[CL 24562359 by brian bekich in ue5-main branch]
This commit is contained in:
brian bekich
2023-03-08 12:32:36 -05:00
parent 5b25fedbf6
commit 1663b49a3f
12 changed files with 94 additions and 19 deletions

View File

@@ -17,16 +17,9 @@
"Modules" :
[
{
"Name" : "DTLSHandlerComponent",
"Type" : "Runtime",
"LoadingPhase" : "Default",
"PlatformAllowList":
[
"IOS",
"Mac",
"Win64",
"Linux"
]
"Name": "DTLSHandlerComponent",
"Type": "Runtime",
"LoadingPhase": "Default"
}
]
}

View File

@@ -15,10 +15,33 @@ public class DTLSHandlerComponent : ModuleRules
"NetCore",
"PacketHandler",
"Engine",
"SSL",
}
);
AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenSSL");
}
if (bPlatformSupportsOpenSSL)
{
PublicDefinitions.Add("UE_WITH_DTLS=1");
PublicDependencyModuleNames.Add("SSL");
AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenSSL");
}
else
{
PublicDefinitions.Add("UE_WITH_DTLS=0");
PrivateDefinitions.Add("WITH_SSL=0");
}
}
protected virtual bool bPlatformSupportsOpenSSL
{
get
{
return
Target.Platform == UnrealTargetPlatform.Mac ||
Target.Platform == UnrealTargetPlatform.Win64 ||
Target.IsInPlatformGroup(UnrealPlatformGroup.Unix) ||
Target.Platform == UnrealTargetPlatform.IOS ||
Target.Platform == UnrealTargetPlatform.Android;
}
}
}

View File

@@ -6,6 +6,8 @@
#include "Misc/FileHelper.h"
#include "HAL/IConsoleManager.h"
#if WITH_SSL
#if !UE_BUILD_SHIPPING
static TAutoConsoleVariable<int32> CVarDTLSDebugFingerprints(TEXT("DTLS.DebugFingerprints"), 0, TEXT(""));
#endif
@@ -90,3 +92,5 @@ bool FDTLSCertStore::RemoveCert(const FString& Identifier)
{
return (CertMap.Remove(Identifier) != 0);
}
#endif // WITH_SSL

View File

@@ -5,6 +5,8 @@
#include "Misc/ScopeExit.h"
#include "HAL/FileManager.h"
#if WITH_SSL
#define UI UI_ST
THIRD_PARTY_INCLUDES_START
#include <openssl/asn1.h>
@@ -232,4 +234,6 @@ bool FDTLSCertificate::GenerateFingerprint()
}
return true;
}
}
#endif // WITH_SSL

View File

@@ -5,6 +5,8 @@
#include "DTLSHandlerComponent.h"
#include "DTLSCertStore.h"
#if WITH_SSL
#define UI UI_ST
THIRD_PARTY_INCLUDES_START
#include "Interfaces/ISslCertificateManager.h"
@@ -457,3 +459,6 @@ bool FDTLSContext::IsHandshakeComplete() const
{
return (SSLPtr != nullptr) && SSL_is_init_finished(SSLPtr);
}
#endif // WITH_SSL

View File

@@ -2,6 +2,8 @@
#include "DTLSHandlerComponent.h"
#if WITH_SSL
#define UI UI_ST
THIRD_PARTY_INCLUDES_START
#include "DTLSCertificate.h"
@@ -20,16 +22,19 @@ THIRD_PARTY_INCLUDES_START
THIRD_PARTY_INCLUDES_END
#undef UI
TAutoConsoleVariable<int32> CVarPreSharedKeys(TEXT("DTLS.PreSharedKeys"), 1, TEXT("If non-zero, use pre-shared keys, otherwise self-signed certificates will be generated."));
#endif // WITH_SSL
DEFINE_LOG_CATEGORY(LogDTLSHandler);
IMPLEMENT_MODULE(FDTLSHandlerComponentModule, DTLSHandlerComponent)
TAutoConsoleVariable<int32> CVarPreSharedKeys(TEXT("DTLS.PreSharedKeys"), 1, TEXT("If non-zero, use pre-shared keys, otherwise self-signed certificates will be generated."));
void FDTLSHandlerComponentModule::StartupModule()
{
FPacketHandlerComponentModuleInterface::StartupModule();
#if WITH_SSL
FSslModule& SslModule = FModuleManager::LoadModuleChecked<FSslModule>("SSL");
if (!SslModule.GetSslManager().InitializeSsl())
{
@@ -37,23 +42,31 @@ void FDTLSHandlerComponentModule::StartupModule()
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
}
#endif // WITH_SSL
}
void FDTLSHandlerComponentModule::ShutdownModule()
{
#if WITH_SSL
FSslModule& SslModule = FModuleManager::LoadModuleChecked<FSslModule>("SSL");
SslModule.GetSslManager().ShutdownSsl();
#endif // WITH_SSL
FPacketHandlerComponentModuleInterface::ShutdownModule();
}
TSharedPtr<HandlerComponent> FDTLSHandlerComponentModule::CreateComponentInstance(FString& Options)
{
#if WITH_SSL
TSharedRef<HandlerComponent> ReturnVal = MakeShared<FDTLSHandlerComponent>();
return ReturnVal;
#else
return nullptr;
#endif // WITH_SSL
}
#if WITH_SSL
FDTLSHandlerComponent::FDTLSHandlerComponent()
: FEncryptionComponent(FName(TEXT("DTLSHandlerComponent")))
, InternalState(EDTLSHandlerState::Unencrypted)
@@ -525,3 +538,5 @@ void FDTLSHandlerComponent::LogError(const TCHAR* Context, int32 Result)
UE_LOG(LogDTLSHandler, Error, TEXT("%s: ERR_print_errors: %s"), Context, *ErrorString);
}
}
#endif // WITH_SSL

View File

@@ -5,6 +5,8 @@
#include "DTLSHandlerTypes.h"
#include "DTLSCertificate.h"
#if WITH_SSL
/*
* Certificate store that can generate self-signed X509 certificates for DTLS
*/
@@ -79,3 +81,5 @@ private:
static TUniquePtr<FDTLSCertStore> Instance;
};
#endif // WITH_SSL

View File

@@ -5,6 +5,8 @@
#include "DTLSHandlerTypes.h"
#include "Misc/Timespan.h"
#if WITH_SSL
/*
* Wrapper for a fingerprint (SHA256 hash) of an X509 certificate
*/
@@ -88,4 +90,6 @@ private:
EVP_PKEY* PKey;
X509* Certificate;
FDTLSFingerprint Fingerprint;
};
};
#endif // WITH_SSL

View File

@@ -5,6 +5,8 @@
#include "DTLSHandlerTypes.h"
#include "DTLSCertificate.h"
#if WITH_SSL
class FDTLSHandlerComponent;
/*
@@ -117,3 +119,5 @@ private:
TSharedPtr<FDTLSCertificate> Cert;
};
#endif // WITH_SSL

View File

@@ -9,6 +9,8 @@
#include "UObject/CoreNet.h"
#include "DTLSContext.h"
#if WITH_SSL
extern TAutoConsoleVariable<int32> CVarPreSharedKeys;
/*
@@ -75,6 +77,8 @@ private:
bool bPendingHandshakeData;
};
#endif // WITH_SSL
/**
* The public interface to this module.
*/

View File

@@ -4,7 +4,7 @@
#include "CoreMinimal.h"
DECLARE_LOG_CATEGORY_EXTERN(LogDTLSHandler, Log, All);
#if WITH_SSL
/** Forward some OpenSSL types */
@@ -31,4 +31,8 @@ enum class EDTLSContextType
Client
};
const TCHAR* LexToString(EDTLSContextType ContextType);
const TCHAR* LexToString(EDTLSContextType ContextType);
#endif // WITH_SSL
DECLARE_LOG_CATEGORY_EXTERN(LogDTLSHandler, Log, All);

View File

@@ -8,9 +8,12 @@
#include "LyraGameplayTags.h"
#include "Player/LyraPlayerController.h"
#include "GameFramework/PlayerState.h"
#if UE_WITH_DTLS
#include "DTLSCertStore.h"
#include "DTLSHandlerComponent.h"
#include "Misc/FileHelper.h"
#endif // UE_WITH_DTLS
#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraGameInstance)
@@ -23,6 +26,7 @@ namespace Lyra
TEXT("If true, clients will send an encryption token with their request to join the server and attempt to encrypt the connection using a debug key. This is NOT SECURE and for demonstration purposes only."),
ECVF_Default);
#if UE_WITH_DTLS
static bool bUseDTLSEncryption = false;
static FAutoConsoleVariableRef CVarLyraUseDTLSEncryption(
TEXT("Lyra.UseDTLSEncryption"),
@@ -70,6 +74,7 @@ namespace Lyra
}
}));
#endif // UE_BUILD_SHIPPING
#endif // UE_WITH_DTLS
};
ULyraGameInstance::ULyraGameInstance(const FObjectInitializer& ObjectInitializer)
@@ -149,6 +154,7 @@ void ULyraGameInstance::ReceivedNetworkEncryptionToken(const FString& Encryption
}
else
{
#if UE_WITH_DTLS
if (Lyra::bUseDTLSEncryption)
{
TSharedPtr<FDTLSCertificate> Cert;
@@ -199,6 +205,7 @@ void ULyraGameInstance::ReceivedNetworkEncryptionToken(const FString& Encryption
}
}
else
#endif // UE_WITH_DTLS
{
Response.Response = EEncryptionResponse::Success;
Response.EncryptionData.Key = DebugTestEncryptionKey;
@@ -217,6 +224,7 @@ void ULyraGameInstance::ReceivedNetworkEncryptionAck(const FOnEncryptionKeyRespo
FEncryptionKeyResponse Response;
#if UE_WITH_DTLS
if (Lyra::bUseDTLSEncryption)
{
Response.Response = EEncryptionResponse::Failure;
@@ -273,6 +281,7 @@ void ULyraGameInstance::ReceivedNetworkEncryptionAck(const FOnEncryptionKeyRespo
}
}
else
#endif // UE_WITH_DTLS
{
Response.Response = EEncryptionResponse::Success;
Response.EncryptionData.Key = DebugTestEncryptionKey;
@@ -286,6 +295,7 @@ void ULyraGameInstance::OnPreClientTravelToSession(FString& URL)
// Add debug encryption token if desired.
if (Lyra::bTestEncryption)
{
#if UE_WITH_DTLS
if (Lyra::bUseDTLSEncryption)
{
APlayerController* const PlayerController = GetFirstLocalPlayerController();
@@ -299,6 +309,7 @@ void ULyraGameInstance::OnPreClientTravelToSession(FString& URL)
}
}
else
#endif // UE_WITH_DTLS
{
// This is just a value for testing/debugging, the server will use the same key regardless of the token value.
// But the token could be a user ID and/or session ID that would be used to generate a unique key per user and/or session, if desired.