aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2022-02-07 15:46:51 +0100
committerPer Larsson <[email protected]>2022-02-07 15:46:51 +0100
commit4b3d9873def5e974fd47a5360a3eff4095aab88b (patch)
tree23196dba05475cbec6bb6141e08390fcd44d6961
parentReplaced crypto transform abstraction with a concrete API. (diff)
downloadzen-4b3d9873def5e974fd47a5360a3eff4095aab88b.tar.xz
zen-4b3d9873def5e974fd47a5360a3eff4095aab88b.zip
Refactored auth manager to use simplified encryption API.
-rw-r--r--zencore/crypto.cpp25
-rw-r--r--zenserver/auth/authmgr.cpp81
-rw-r--r--zenserver/auth/authmgr.h12
-rw-r--r--zenserver/config.cpp27
-rw-r--r--zenserver/zenserver.cpp37
5 files changed, 102 insertions, 80 deletions
diff --git a/zencore/crypto.cpp b/zencore/crypto.cpp
index 0ad368f3f..448fd36fa 100644
--- a/zencore/crypto.cpp
+++ b/zencore/crypto.cpp
@@ -64,10 +64,7 @@ namespace crypto {
if (Err != 1)
{
- if (Reason)
- {
- Reason = fmt::format("failed to initialize cipher, error code '{}'", Err);
- }
+ Reason = fmt::format("failed to initialize cipher, error code '{}'", Err);
return MemoryView();
}
@@ -83,10 +80,7 @@ namespace crypto {
if (Err != 1)
{
- if (Reason)
- {
- Reason = fmt::format("update crypto transform failed, error code '{}'", Err);
- }
+ Reason = fmt::format("update crypto transform failed, error code '{}'", Err);
return MemoryView();
}
@@ -100,10 +94,7 @@ namespace crypto {
if (Err != 1)
{
- if (Reason)
- {
- Reason = fmt::format("finalize crypto transform failed, error code '{}'", Err);
- }
+ Reason = fmt::format("finalize crypto transform failed, error code '{}'", Err);
return MemoryView();
}
@@ -117,20 +108,14 @@ namespace crypto {
{
if (Key.IsValid() == false)
{
- if (Reason)
- {
- Reason = "Invalid key"sv;
- }
+ Reason = "invalid key"sv;
return false;
}
if (IV.IsValid() == false)
{
- if (Reason)
- {
- Reason = "Invalid initialization vector"sv;
- }
+ Reason = "invalid initialization vector"sv;
return false;
}
diff --git a/zenserver/auth/authmgr.cpp b/zenserver/auth/authmgr.cpp
index 2c54386ee..223fcbfe2 100644
--- a/zenserver/auth/authmgr.cpp
+++ b/zenserver/auth/authmgr.cpp
@@ -23,7 +23,10 @@ namespace zen {
using namespace std::literals;
namespace details {
- IoBuffer ReadEncryptedFile(std::filesystem::path Path, MemoryView EncryptionKey, MemoryView IV)
+ IoBuffer ReadEncryptedFile(std::filesystem::path Path,
+ const AesKey256Bit& Key,
+ const AesIV128Bit& IV,
+ std::optional<std::string>& Reason)
{
FileContents Result = ReadFile(Path);
@@ -39,53 +42,45 @@ namespace details {
return IoBuffer();
}
- std::unique_ptr<SymmetricCipher> Cipher = SymmetricCipher::CreateAes();
+ std::vector<uint8_t> DecryptionBuffer;
+ DecryptionBuffer.resize(EncryptedBuffer.GetSize() + Aes::BlockSize);
- if (Cipher->Initialize(EncryptionKey, IV) == false)
+ MemoryView DecryptedView = Aes::Decrypt(Key, IV, EncryptedBuffer, MakeMutableMemoryView(DecryptionBuffer), Reason);
+
+ if (DecryptedView.IsEmpty())
{
return IoBuffer();
}
- IoBuffer DecryptionBuffer(EncryptedBuffer.GetSize() + Cipher->Settings().BlockSize);
- MemoryView DecryptedView = Cipher->Decrypt(EncryptedBuffer, DecryptionBuffer.GetMutableView());
-
return IoBufferBuilder::MakeCloneFromMemory(DecryptedView);
}
- uint64_t WriteEncryptedFile(std::filesystem::path Path, IoBuffer FileData, MemoryView EncryptionKey, MemoryView IV)
+ void WriteEncryptedFile(std::filesystem::path Path,
+ IoBuffer FileData,
+ const AesKey256Bit& Key,
+ const AesIV128Bit& IV,
+ std::optional<std::string>& Reason)
{
if (FileData.GetSize() == 0)
{
- return 0;
+ return;
}
- std::unique_ptr<SymmetricCipher> Cipher = SymmetricCipher::CreateAes();
+ std::vector<uint8_t> EncryptionBuffer;
+ ;
+ EncryptionBuffer.resize(FileData.GetSize() + Aes::BlockSize);
- if (Cipher->Initialize(EncryptionKey, IV) == false)
+ MemoryView EncryptedView = Aes::Encrypt(Key, IV, FileData, MakeMutableMemoryView(EncryptionBuffer), Reason);
+
+ if (EncryptedView.IsEmpty())
{
- return 0;
+ return;
}
- IoBuffer EncryptionBuffer(FileData.GetSize() + Cipher->Settings().BlockSize);
-
- MemoryView EncryptedView = Cipher->Encrypt(FileData, EncryptionBuffer.GetMutableView());
-
WriteFile(Path, IoBuffer(IoBuffer::Wrap, EncryptedView.GetData(), EncryptedView.GetSize()));
-
- return EncryptedView.GetSize();
}
} // namespace details
-AuthEncryptionKey
-AuthEncryptionKey::Default()
-{
- const std::string_view DefaultKey = "HeyThisIsNotAGoodPrivateKeyToUse"sv;
- const std::string_view DefaultIV = "DefaultInitVecto"sv;
-
- return {.Key = IoBufferBuilder::MakeCloneFromMemory(MakeMemoryView(DefaultKey)),
- .IV = IoBufferBuilder::MakeCloneFromMemory(MakeMemoryView(DefaultIV))};
-}
-
class AuthMgrImpl final : public AuthMgr
{
using Clock = std::chrono::system_clock;
@@ -95,12 +90,6 @@ class AuthMgrImpl final : public AuthMgr
public:
AuthMgrImpl(const AuthConfig& Config) : m_Config(Config), m_Log(logging::Get("auth"))
{
- if (!m_Config.EncryptionKey.Key || !m_Config.EncryptionKey.IV)
- {
- ZEN_WARN("using default encryption key");
- m_Config.EncryptionKey = AuthEncryptionKey::Default();
- }
-
LoadState();
m_BackgroundThread.Interval = Config.UpdateInterval;
@@ -248,11 +237,18 @@ private:
{
try
{
+ std::optional<std::string> Reason;
+
IoBuffer Buffer =
- details::ReadEncryptedFile(m_Config.RootDirectory / "authstate"sv, m_Config.EncryptionKey.Key, m_Config.EncryptionKey.IV);
+ details::ReadEncryptedFile(m_Config.RootDirectory / "authstate"sv, m_Config.EncryptionKey, m_Config.EncryptionIV, Reason);
- if (Buffer.GetSize() == 0)
+ if (!Buffer)
{
+ if (Reason)
+ {
+ ZEN_WARN("load auth state FAILED, reason '{}'", Reason.value());
+ }
+
return;
}
@@ -352,14 +348,17 @@ private:
std::filesystem::create_directories(m_Config.RootDirectory);
- const uint64_t ByteCount = details::WriteEncryptedFile(m_Config.RootDirectory / "authstate"sv,
- AuthState.Save().GetBuffer().AsIoBuffer(),
- m_Config.EncryptionKey.Key,
- m_Config.EncryptionKey.IV);
+ std::optional<std::string> Reason;
+
+ details::WriteEncryptedFile(m_Config.RootDirectory / "authstate"sv,
+ AuthState.Save().GetBuffer().AsIoBuffer(),
+ m_Config.EncryptionKey,
+ m_Config.EncryptionIV,
+ Reason);
- if (ByteCount == 0)
+ if (Reason)
{
- ZEN_WARN("save auth state FAILED");
+ ZEN_WARN("save auth state FAILED, reason '{}'", Reason.value());
}
}
catch (std::exception& Err)
diff --git a/zenserver/auth/authmgr.h b/zenserver/auth/authmgr.h
index a641b9c8f..0354bdbfa 100644
--- a/zenserver/auth/authmgr.h
+++ b/zenserver/auth/authmgr.h
@@ -1,5 +1,6 @@
// Copyright Epic Games, Inc. All Rights Reserved.
+#include <zencore/crypto.h>
#include <zencore/iobuffer.h>
#include <zencore/string.h>
@@ -9,19 +10,12 @@
namespace zen {
-struct AuthEncryptionKey
-{
- IoBuffer Key;
- IoBuffer IV;
-
- static AuthEncryptionKey Default();
-};
-
struct AuthConfig
{
std::filesystem::path RootDirectory;
std::chrono::seconds UpdateInterval{30};
- AuthEncryptionKey EncryptionKey;
+ AesKey256Bit EncryptionKey;
+ AesIV128Bit EncryptionIV;
};
class AuthMgr
diff --git a/zenserver/config.cpp b/zenserver/config.cpp
index 14908b615..cb6d5ea6d 100644
--- a/zenserver/config.cpp
+++ b/zenserver/config.cpp
@@ -4,6 +4,7 @@
#include "diag/logging.h"
+#include <zencore/crypto.h>
#include <zencore/fmtutils.h>
#include <zencore/iobuffer.h>
#include <zencore/string.h>
@@ -59,6 +60,30 @@ PickDefaultStateDirectory()
#endif
+void
+ValidateOptions(ZenServerOptions& ServerOptions)
+{
+ if (ServerOptions.EncryptionKey.empty() == false)
+ {
+ const auto Key = zen::AesKey256Bit::FromString(ServerOptions.EncryptionKey);
+
+ if (Key.IsValid() == false)
+ {
+ throw cxxopts::OptionParseException("Invalid AES encryption key");
+ }
+ }
+
+ if (ServerOptions.EncryptionIV.empty() == false)
+ {
+ const auto IV = zen::AesIV128Bit::FromString(ServerOptions.EncryptionIV);
+
+ if (IV.IsValid() == false)
+ {
+ throw cxxopts::OptionParseException("Invalid AES initialization vector");
+ }
+ }
+}
+
UpstreamCachePolicy
ParseUpstreamCachePolicy(std::string_view Options)
{
@@ -365,6 +390,8 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
{
ParseConfigFile(ServerOptions.DataDir / "zen_cfg.lua", ServerOptions);
}
+
+ ValidateOptions(ServerOptions);
}
catch (cxxopts::OptionParseException& e)
{
diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp
index c1a5fe507..fca567f28 100644
--- a/zenserver/zenserver.cpp
+++ b/zenserver/zenserver.cpp
@@ -204,21 +204,38 @@ public:
m_Http = zen::CreateHttpServer(ServerOptions.HttpServerClass);
int EffectiveBasePort = m_Http->Initialize(ServerOptions.BasePort);
- AuthEncryptionKey EncryptionKey;
-
- if (ServerOptions.EncryptionKey.empty() == false && ServerOptions.EncryptionIV.empty() == false)
+ // Setup authentication manager
{
- EncryptionKey = AuthEncryptionKey{.Key = IoBufferBuilder::MakeCloneFromMemory(MakeMemoryView(ServerOptions.EncryptionKey)),
- .IV = IoBufferBuilder::MakeCloneFromMemory(MakeMemoryView(ServerOptions.EncryptionIV))};
- };
+ std::string EncryptionKey = ServerOptions.EncryptionKey;
+
+ if (EncryptionKey.empty())
+ {
+ EncryptionKey = "abcdefghijklmnopqrstuvxyz0123456";
+
+ ZEN_WARN("using default encryption key");
+ }
+
+ std::string EncryptionIV = ServerOptions.EncryptionIV;
+
+ if (EncryptionIV.empty())
+ {
+ EncryptionIV = "0123456789abcdef";
+
+ ZEN_WARN("using default encryption initialization vector");
+ }
+
+ m_AuthMgr = AuthMgr::Create({.RootDirectory = m_DataRoot / "auth",
+ .EncryptionKey = AesKey256Bit::FromString(EncryptionKey),
+ .EncryptionIV = AesIV128Bit::FromString(EncryptionIV)});
+
+ m_AuthMgr->AddOpenIdProvider({.Name = "Okta"sv,
+ .Url = "https://epicgames.okta.com/oauth2/auso645ojjWVdRI3d0x7"sv,
+ .ClientId = "0oapq1knoglGFqQvr0x7"sv});
+ }
- m_AuthMgr = AuthMgr::Create({.RootDirectory = m_DataRoot / "auth", .EncryptionKey = EncryptionKey});
m_AuthService = std::make_unique<zen::HttpAuthService>(*m_AuthMgr);
m_Http->RegisterService(*m_AuthService);
- m_AuthMgr->AddOpenIdProvider(
- {.Name = "Okta"sv, .Url = "https://epicgames.okta.com/oauth2/auso645ojjWVdRI3d0x7"sv, .ClientId = "0oapq1knoglGFqQvr0x7"sv});
-
m_Http->RegisterService(m_HealthService);
m_Http->RegisterService(m_StatsService);
m_Http->RegisterService(m_StatusService);