diff --git a/Dalamud.Bootstrap/Crypto/Blowfish.cs b/Dalamud.Bootstrap/Crypto/Blowfish.cs index cca5c1c48..6e23a9ab3 100644 --- a/Dalamud.Bootstrap/Crypto/Blowfish.cs +++ b/Dalamud.Bootstrap/Crypto/Blowfish.cs @@ -15,6 +15,8 @@ namespace Dalamud.Bootstrap.Crypto /// internal sealed class Blowfish { + public static int BlockSize => 8; + private BlowfishState m_state; /// @@ -50,7 +52,7 @@ namespace Dalamud.Bootstrap.Crypto private static bool CheckBufferLength(int length) => length switch { - _ when length % 8 == 0 => true, + _ when length % BlockSize == 0 => true, _ => false, }; diff --git a/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs b/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs index bff5de6a4..954858ecc 100644 --- a/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs +++ b/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs @@ -26,6 +26,19 @@ namespace Dalamud.Bootstrap.SqexArg return this; } + public bool ContainsKey(string key) => m_dict.ContainsKey(key); + + public bool ContainsValue(string value) => m_dict.ContainsValue(value); + + public ArgumentBuilder Remove(string key) + { + m_dict.Remove(key); + + return this; + } + + public bool TryRemove(string key) => m_dict.Remove(key); + private static void Write(StringBuilder buffer, string key, string value) { var escapedKey = EscapeValue(key); diff --git a/Dalamud.Bootstrap/SqexArg/EncryptedArgument.cs b/Dalamud.Bootstrap/SqexArg/EncryptedArgument.cs index 54b449d86..210bc251d 100644 --- a/Dalamud.Bootstrap/SqexArg/EncryptedArgument.cs +++ b/Dalamud.Bootstrap/SqexArg/EncryptedArgument.cs @@ -53,7 +53,7 @@ namespace Dalamud.Bootstrap.SqexArg } /// - /// + /// Extracts the payload and checksum from the encrypted argument. /// /// /// An encrypted payload encoded in url-safe base64 string extracted. The value is undefined if the function fails. @@ -83,6 +83,13 @@ namespace Dalamud.Bootstrap.SqexArg Span keyBytes = stackalloc byte[8]; CreateKey(key, keyBytes); + if (!Extract(argument, out var encryptedStr, out var _)) + { + throw new SqexArgException($"Could not extract the argument and checksum from {argument}"); + } + + var encryptedData = DecodeUrlSafeBase64(encryptedStr); + // Allocate the buffer to store decrypted data var decryptedData = CreateAlignedBuffer(encryptedData.Length); @@ -101,25 +108,24 @@ namespace Dalamud.Bootstrap.SqexArg return new EncryptedArgument(decryptedData); } - private static IMemoryOwner CreateAlignedBuffer(int minimumSize) - { - // align (by padding) to block size if needed - throw new NotImplementedException("TODO"); - } - /// /// /// - /// - /// - private static bool CheckDecryptedData(ReadOnlySpan decryptedData) + /// Indicates that returned buffer must be larger than `minimumSize` bytes. + /// + /// A buffer aligned to next multiple of block size. + /// Dispose() must be called when it's not used anymore. + /// + private static IMemoryOwner CreateAlignedBuffer(int minimumSize) { - // TODO - return false; + // align to next multiple of block size. + var alignedSize = (minimumSize + Blowfish.BlockSize - 1) & (~(-Blowfish.BlockSize)); + + return MemoryPool.Shared.Rent(alignedSize); } /// - /// Formats the key. + /// Formats a key. /// /// A secret key. /// A buffer where formatted key will be stored. This must be larger than 8 bytes. @@ -127,8 +133,7 @@ namespace Dalamud.Bootstrap.SqexArg { if (!Utf8Formatter.TryFormat(key, destination, out var _, new StandardFormat('x', 8))) { - var message = $"BUG: Could not create a key"; // This should not fail but.. - throw new InvalidOperationException(message); + throw new InvalidOperationException("BUG: Could not create a key"); } } @@ -144,5 +149,10 @@ namespace Dalamud.Bootstrap.SqexArg return Convert.FromBase64String(base64Str); } + + public string Encrypt(uint key) + { + + } } }