mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-10 15:20:48 -05:00
implement remote assembly loading
This commit is contained in:
76
Application/Misc/RemoteAssemblyHandler.cs
Normal file
76
Application/Misc/RemoteAssemblyHandler.cs
Normal file
@ -0,0 +1,76 @@
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace IW4MAdmin.Application.Misc
|
||||
{
|
||||
public class RemoteAssemblyHandler : IRemoteAssemblyHandler
|
||||
{
|
||||
private const int keyLength = 32;
|
||||
private const int tagLength = 16;
|
||||
private const int nonceLength = 12;
|
||||
private const int iterationCount = 10000;
|
||||
|
||||
private readonly ApplicationConfiguration _appconfig;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public RemoteAssemblyHandler(ILogger logger, ApplicationConfiguration appconfig)
|
||||
{
|
||||
_appconfig = appconfig;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public IEnumerable<Assembly> DecryptAssemblies(string[] encryptedAssemblies)
|
||||
{
|
||||
return DecryptContent(encryptedAssemblies)
|
||||
.Select(decryptedAssembly => Assembly.Load(decryptedAssembly));
|
||||
}
|
||||
|
||||
public IEnumerable<string> DecryptScripts(string[] encryptedScripts)
|
||||
{
|
||||
return DecryptContent(encryptedScripts).Select(decryptedScript => Encoding.UTF8.GetString(decryptedScript));
|
||||
}
|
||||
|
||||
private byte[][] DecryptContent(string[] content)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_appconfig.Id) || string.IsNullOrWhiteSpace(_appconfig.SubscriptionId))
|
||||
{
|
||||
_logger.WriteWarning($"{nameof(_appconfig.Id)} and {nameof(_appconfig.SubscriptionId)} must be provided to attempt loading remote assemblies/scripts");
|
||||
return new byte[0][];
|
||||
}
|
||||
|
||||
var assemblies = content.Select(piece =>
|
||||
{
|
||||
byte[] byteContent = Convert.FromBase64String(piece);
|
||||
byte[] encryptedContent = byteContent.Take(byteContent.Length - (tagLength + nonceLength)).ToArray();
|
||||
byte[] tag = byteContent.Skip(byteContent.Length - (tagLength + nonceLength)).Take(tagLength).ToArray();
|
||||
byte[] nonce = byteContent.Skip(byteContent.Length - nonceLength).Take(nonceLength).ToArray();
|
||||
byte[] decryptedContent = new byte[encryptedContent.Length];
|
||||
|
||||
var keyGen = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(_appconfig.SubscriptionId), Encoding.UTF8.GetBytes(_appconfig.Id.ToString()), iterationCount, HashAlgorithmName.SHA512);
|
||||
var encryption = new AesGcm(keyGen.GetBytes(keyLength));
|
||||
|
||||
try
|
||||
{
|
||||
encryption.Decrypt(nonce, encryptedContent, tag, decryptedContent);
|
||||
}
|
||||
|
||||
catch (CryptographicException ex)
|
||||
{
|
||||
_logger.WriteError("Could not obtain remote plugin assemblies");
|
||||
_logger.WriteDebug(ex.GetExceptionInfo());
|
||||
}
|
||||
|
||||
return decryptedContent;
|
||||
});
|
||||
|
||||
return assemblies.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user