summaryrefslogtreecommitdiff
path: root/ArchSecurity.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xArchSecurity.cs130
1 files changed, 130 insertions, 0 deletions
diff --git a/ArchSecurity.cs b/ArchSecurity.cs
new file mode 100755
index 0000000..60f7047
--- /dev/null
+++ b/ArchSecurity.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OtpSharp;
+
+namespace ArchBreaker
+{
+ static class ArchSecurity
+ {
+ public static string GenerateAssertion(string issuer)
+ {
+ var totpObj = new Totp(Encoding.UTF8.GetBytes(issuer), step: 600, totpSize: 8);
+ var totp = totpObj.ComputeTotp();
+
+ var payload = new Dictionary<string, object>()
+ {
+ {"aud", Constants.BaasBaseURL},
+ {"iss", issuer}
+ };
+
+ return Jose.JWT.Encode(payload, Encoding.UTF8.GetBytes(totp), Jose.JwsAlgorithm.HS256);
+ }
+
+
+ public static byte[] ComputeKey(string commonKey, string sessionID)
+ {
+ var commonBytes = Encoding.ASCII.GetBytes(commonKey);
+ var sessionBytes = Encoding.ASCII.GetBytes(sessionID);
+ var result = new byte[commonBytes.Length + sessionBytes.Length];
+
+ for (int i = 0; i < commonBytes.Length; i++)
+ result[i] = (byte)(0x9E - commonBytes[i]);
+ Array.Copy(sessionBytes, 0, result, commonBytes.Length, sessionBytes.Length);
+
+ return result;
+ }
+
+
+ public static void TransformPacket(byte[] packet, byte[] key, bool encrypt)
+ {
+ for (int i = 0; i < packet.Length; i++)
+ {
+ int keyOffset = (i + 1) % key.Length;
+ int rot = key[keyOffset] & 7;
+ if (rot == 0)
+ packet[i] ^= key[keyOffset];
+ else
+ {
+ if (encrypt)
+ rot = 8 - rot;
+ packet[i] = (byte)((packet[i] >> (8 - rot)) | (packet[i] << rot));
+ }
+ }
+ }
+
+
+ public static byte[] DecompressPacket(byte[] input)
+ {
+ var hdr = ReadLZ4Header(input);
+ int destSize = hdr.Item1, offset = hdr.Item2;
+
+ var output = new byte[destSize];
+ LZ4PCL.LZ4Codec.Decode(
+ input, offset, input.Length - offset,
+ output, 0, destSize,
+ true);
+ return output;
+ }
+ public static byte[] CompressPacket(byte[] input)
+ {
+ var buf = new byte[LZ4PCL.LZ4Codec.MaximumOutputLength(input.Length)];
+
+ int realSize = LZ4PCL.LZ4Codec.Encode(
+ input, 0, input.Length,
+ buf, 0, buf.Length);
+
+ // Pack the header for ruby-lz4 compat
+ var header = new byte[5];
+ int headerSize = 0;
+ int inputSize = input.Length;
+ do
+ {
+ byte b = (byte)(inputSize & 0x7F);
+ inputSize >>= 7;
+
+ if (inputSize == 0)
+ header[headerSize++] = b;
+ else
+ header[headerSize++] = (byte)(b | 0x80);
+ } while (inputSize != 0);
+
+ // Combine header + output into one final array
+ var output = new byte[headerSize + realSize];
+ Array.Copy(header, 0, output, 0, headerSize);
+ Array.Copy(buf, 0, output, headerSize, realSize);
+ return output;
+ }
+
+
+ private static Tuple<int, int> ReadLZ4Header(byte[] buffer)
+ {
+ int destSize = 0;
+ for (int i = 0; i < 5; i++)
+ {
+ int v = buffer[i];
+ destSize |= ((v & 0x7F) << (7 * i));
+
+ if ((v & 0x80) == 0)
+ return new Tuple<int, int>(destSize, i + 1);
+ }
+ return new Tuple<int, int>(-1, -1);
+ }
+
+
+ private static readonly Random _prng = new Random();
+
+ public static string RandomString(int size)
+ {
+ const string pool = "abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPRSTUVWXYZ0123456789";
+
+ var result = new char[size];
+ for (int i = 0; i < size; i++)
+ result[i] = pool[_prng.Next(pool.Length)];
+
+ return new string(result);
+ }
+ }
+}