namespace PerpetuumSoft.Widgets.Licensing
{
    using System;
    using System.Collections.Specialized;
    using System.Security.Cryptography;
    using System.Text;

    public class LicensingUtilities
    {
        private static string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        private static RSACryptoServiceProvider cryptoServiceProvider = null;
        public static string DesignTimeSignatureName = "DesignTimeSignature";
        private static readonly object lockObject = new object();
        private static string PerpetuumSoftDesignTimePublicKey = "<RSAKeyValue><Modulus>2lsccUCy5lRS3FlnjdVIorg5j2tDxsKJGlkxYK3BNC6Y3jdEOI/hz66smBi3wo4eQAdKn1+6hqUZpte/rwLIMyVsWso1PFxVAhSYgkvsl56oIFwHrm46Rr/coa3sppoxk/Xga6CKVWFYqfkHCVfZrO268dcnFunc+ZYrVpKaPzk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
        private static string PerpetuumSoftRunTimePublicKey = "<RSAKeyValue><Modulus>mlSYsW9zP25U/pgr0o98pesNDlX13hPwR1iwlX/hJGHgkGy9C2NtDoEKLZ3c+Ie6rYhD4wHzV81YFjzkntv0S+pkDIyTakoWZ2S45TG8OHKF9zZgMpNiWUT9KWGU1dmPTbI/x932YgqvfKCFzxo6N8vS7GHp2jUoS/DOmIKS7lE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
        public static string RunTimeSignatureName = "RunTimeSignature";

        public static bool CheckDesignTimeLicenseKey(string licenseKey)
        {
            NameValueCollection license = ParseLicenseKey(licenseKey);
            string designTimeLicenseText = GetDesignTimeLicenseText(license);
            string signText = license[DesignTimeSignatureName];
            if (signText == null)
            {
                signText = string.Empty;
            }
            return CheckSign(designTimeLicenseText, signText, PerpetuumSoftDesignTimePublicKey);
        }

        public static PerpetuumSoftLicense CheckRegKey(PerpetuumSoftLicense license, string newRegKey)
        {
            if ((!ValidRegKey(license, newRegKey) && (license != null)) && !license.IsTrial)
            {
                using (WarningForm form = new WarningForm())
                {
                    form.ShowDialog();
                }
            }
            return license;
        }

        public static bool CheckRunTimeLicenseKey(string licenseKey)
        {
            NameValueCollection license = ParseLicenseKey(licenseKey);
            return CheckSign(GetRunTimeLicenseText(license), license[RunTimeSignatureName], PerpetuumSoftRunTimePublicKey);
        }

        public static bool CheckSign(string licenseText, string signText, string publicKey)
        {
            byte[] rgbSignature = Decode(signText);
            byte[] bytes = Encoding.Unicode.GetBytes(licenseText);
            byte[] rgbHash = new SHA1CryptoServiceProvider().ComputeHash(bytes);
            lock (lockObject)
            {
                if (cryptoServiceProvider == null)
                {
                    cryptoServiceProvider = CreateCryptoServiceProvider();
                }
                cryptoServiceProvider.FromXmlString(publicKey);
                RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(cryptoServiceProvider);
                deformatter.SetHashAlgorithm("SHA1");
                return deformatter.VerifySignature(rgbHash, rgbSignature);
            }
        }

        private static RSACryptoServiceProvider CreateCryptoServiceProvider()
        {
            try
            {
                return new RSACryptoServiceProvider(0x400);
            }
            catch (CryptographicException)
            {
                CspParameters parameters = new CspParameters(1);
                parameters.KeyContainerName = "PerpetuumSoftContainer";
                parameters.Flags = CspProviderFlags.UseMachineKeyStore;
                return new RSACryptoServiceProvider(0x400, parameters);
            }
        }

        public static byte[] Decode(string text)
        {
            if (text == null)
            {
                text = string.Empty;
            }
            byte[] buffer = new byte[text.Length / 2];
            for (int i = 0; i < (buffer.Length * 2); i += 2)
            {
                buffer[i / 2] = (byte) ((alphabet.IndexOf(text[i]) * alphabet.Length) + alphabet.IndexOf(text[i + 1]));
            }
            return buffer;
        }

        public static string DecodeLicenseKey(string text)
        {
            StringBuilder builder = new StringBuilder();
            bool flag = false;
            for (int i = 0; i < text.Length; i++)
            {
                if (!flag && (text[i] == '{'))
                {
                    flag = true;
                }
                else
                {
                    if (text[i] == '}')
                    {
                        break;
                    }
                    if (alphabet.IndexOf(text[i]) != -1)
                    {
                        builder.Append(text[i]);
                    }
                }
            }
            return Encoding.Unicode.GetString(Decode(builder.ToString()));
        }

        public static string Encode(byte[] bytes, bool split)
        {
            StringBuilder builder = new StringBuilder();
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    if ((split && ((i % 0x20) == 0)) && (i > 0))
                    {
                        builder.Append("\r\n");
                    }
                    builder.Append(alphabet[bytes[i] / alphabet.Length]);
                    builder.Append(alphabet[bytes[i] % alphabet.Length]);
                }
            }
            return builder.ToString();
        }

        public static string EncodeLicenseKey(string licenseKey, bool split)
        {
            return ("{" + Encode(Encoding.Unicode.GetBytes(licenseKey), split) + "}");
        }

        public static string GetDesignTimeLicenseText(NameValueCollection license)
        {
            NameValueCollection values = new NameValueCollection();
            foreach (string str in license.Keys)
            {
                if (str != DesignTimeSignatureName)
                {
                    values.Add(str, license[str]);
                }
            }
            StringBuilder builder = new StringBuilder();
            foreach (string str2 in values.Keys)
            {
                builder.Append(str2);
                builder.Append("=");
                builder.Append(values[str2] + "\r\n");
            }
            return builder.ToString();
        }

        public static string GetRunTimeLicenseText(NameValueCollection license)
        {
            NameValueCollection values = new NameValueCollection();
            foreach (string str in license.Keys)
            {
                if ((str != DesignTimeSignatureName) && (str != RunTimeSignatureName))
                {
                    values.Add(str, license[str]);
                }
            }
            StringBuilder builder = new StringBuilder();
            foreach (string str2 in values.Keys)
            {
                builder.Append(str2);
                builder.Append("=");
                builder.Append(values[str2] + "\r\n");
            }
            return builder.ToString();
        }

        public static NameValueCollection ParseLicenseKey(string licenseKey)
        {
            NameValueCollection values = new NameValueCollection();
            string[] strArray = (licenseKey + "\n").Replace("\r", "").Split(new char[] { '\n' });
            for (int i = 0; i < strArray.Length; i++)
            {
                if (strArray[i].Length > 0)
                {
                    int index = strArray[i].IndexOf("=");
                    if (index <= 0)
                    {
                        throw new FormatException("License key has invalid format");
                    }
                    string str = strArray[i].Substring(0, index).Trim();
                    string str2 = strArray[i].Substring(index + 1).Trim();
                    values[str] = str2;
                }
            }
            return values;
        }

        public static bool ValidRegKey(PerpetuumSoftLicense license, string regKey)
        {
            string[] strArray = regKey.Split(new char[] { '\n' });
            if (license == null)
            {
                return false;
            }
            if (!(strArray[0] != license.RegisteredTo))
            {
                return (strArray[1] == HardwareID);
            }
            return true;
        }

        public static string HardwareID
        {
            get
            {
                return Environment.get_MachineName();
            }
        }
    }
}
