111 lines
3.9 KiB
C#
111 lines
3.9 KiB
C#
|
using System.Globalization;
|
|||
|
using System.Numerics;
|
|||
|
using System.Security.Cryptography;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace AiQ_GUI
|
|||
|
{
|
|||
|
public class Lics
|
|||
|
{
|
|||
|
// Challenge code salts
|
|||
|
const string SAFsalt = "F7W?wbD#'[+:v44]tA<:_iK4hQ}+$R{U";
|
|||
|
const string Streamsalt = "*;5WPsR5i/$8s1I(M)K5=z3fms{_8x4U";
|
|||
|
const string Auditsalt = "4t5e[E06:dXWf:C09Z[h)}V*n>}t0POP";
|
|||
|
const string PasswordSalt = "eP@4^4T2@e@^h12oqf!590";
|
|||
|
|
|||
|
// Generates the license response based on the challenge and type of license
|
|||
|
public static string GenerateLicCode(string challenge, string Type)
|
|||
|
{
|
|||
|
string salt; // Different salts for differnet licenses
|
|||
|
|
|||
|
if (Type == "Store & Forward")
|
|||
|
salt = SAFsalt;
|
|||
|
else if (Type == "Streaming")
|
|||
|
salt = Streamsalt;
|
|||
|
else if (Type == "Audit")
|
|||
|
salt = Auditsalt;
|
|||
|
else
|
|||
|
return "Unrecognised challenge type: " + Type;
|
|||
|
|
|||
|
if (string.IsNullOrEmpty(challenge) || challenge.Length != 6) // Check challenge format
|
|||
|
return "Invalid challenge format. Challenge must be 6 characters.";
|
|||
|
|
|||
|
if (string.IsNullOrEmpty(salt) || salt.Length != 32) // Check salt format
|
|||
|
return "Invalid salt format. Salt must be 32 characters.";
|
|||
|
|
|||
|
// Hash computation using SHA256 algorithm
|
|||
|
byte[] inputBytes = Encoding.UTF8.GetBytes(challenge + " " + salt); // SHA hash format challenge and salt with space between
|
|||
|
byte[] hashBytes = SHA256.HashData(inputBytes);
|
|||
|
|
|||
|
StringBuilder sb = new();
|
|||
|
foreach (byte b in hashBytes)
|
|||
|
{
|
|||
|
sb.Append(b.ToString("x2"));
|
|||
|
}
|
|||
|
string digest = sb.ToString();
|
|||
|
|
|||
|
BigInteger BigInt = BigInteger.Parse("0" + digest, NumberStyles.AllowHexSpecifier); // Leading zero is sign for big int.
|
|||
|
return BigInt.ToString().Substring(0, 6);
|
|||
|
}
|
|||
|
|
|||
|
public static string GeneratePassword(string mac, string version, int time)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string timeBlock = (time / 86400).ToString(); // 1-day validity
|
|||
|
string secret = string.Join(" ", mac, version, timeBlock, PasswordSalt);
|
|||
|
|
|||
|
byte[] digest = MD5.HashData(Encoding.UTF8.GetBytes(secret));
|
|||
|
return Convert.ToBase64String(digest);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
return "Error: Could not generate password " + ex.Message;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void DisplayDevPassword(Versions Vers, Camera CamOnTest)
|
|||
|
{
|
|||
|
CamOnTest.DevPass = FetchDevPassword(Vers);
|
|||
|
|
|||
|
if (CamOnTest.DevPass.Contains("Could not"))
|
|||
|
{
|
|||
|
MainForm.Instance.AddToActionsList(CamOnTest.DevPass); // Did not parse, so error.
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
Network.Initialize("developer", CamOnTest.DevPass); // Reinitialise HTTP client with developer password
|
|||
|
}
|
|||
|
|
|||
|
public static string FetchDevPassword(Versions Vers)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
return GeneratePassword(Vers.MAC, Vers.version, Vers.timeStamp);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
MainForm.Instance.AddToActionsList("Exception in FetchDevPassword: " + ex.Message);
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class Licenses
|
|||
|
{
|
|||
|
public bool saf1 { get; set; }
|
|||
|
public bool saf2 { get; set; }
|
|||
|
public bool saf3 { get; set; }
|
|||
|
public bool saf4 { get; set; }
|
|||
|
public bool audit { get; set; }
|
|||
|
public bool stream { get; set; }
|
|||
|
public string raptorKeyID { get; set; } = string.Empty;
|
|||
|
}
|
|||
|
|
|||
|
public class VaxtorLic
|
|||
|
{
|
|||
|
public string protectionKeyId { get; set; } = string.Empty;
|
|||
|
public string error { get; set; } = string.Empty;
|
|||
|
}
|
|||
|
}
|