From ae40f8e46b872d77a6b4aa445976dbe5b181c8c7 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Mon, 9 Jan 2023 00:32:32 +0000 Subject: [PATCH] --- server/biz/KeyFactory.cs | 348 ++++++++++++++++++++------------------- 1 file changed, 181 insertions(+), 167 deletions(-) diff --git a/server/biz/KeyFactory.cs b/server/biz/KeyFactory.cs index 26a7a14..b938040 100644 --- a/server/biz/KeyFactory.cs +++ b/server/biz/KeyFactory.cs @@ -29,7 +29,7 @@ namespace Sockeye.Biz public const string PLUGIN_RI_KEY = "RI - Responsive Interface"; - private static Dictionary _plugins; + //private static Dictionary _plugins; //Generate a key message reply from a key selection object //CALLED BY LicenseController Generate route @@ -170,7 +170,7 @@ namespace Sockeye.Biz // Extra info to display about key at top of key message - private static string LicenseInfo(dtoKeyOptions ko) + private static string LicenseInfo(License l) { StringBuilder sb = new StringBuilder(); sb.Append("LICENSE DETAILS\r\n"); @@ -184,36 +184,36 @@ namespace Sockeye.Biz // sb.Append("This license will expire and AyaNova usage will be restricted after: " + kg.Expires.ToLongDateString() + "\r\n\r\n"); //} - if (ko.keyWillLockout) + if (l.LicenseExpire != null) { sb.Append("*** This temporary license key is provided for evaluation use only pending payment ***\r\n"); - sb.Append("This license will expire and AyaNova usage will be restricted after: " + DateUtil.EpochToString(ko.lockoutDate) + "\r\n"); + sb.Append($"This license will expire and AyaNova usage will be restricted after: {l.LicenseExpire}\r\n"); sb.Append("\r\n"); sb.Append("A permanent license key will be sent to you when payment \r\n" + "has been received and processed. There will be no extensions or \r\n" + "exceptions. Please send in payment early enough to allow for \r\n" + - "mail and processing time to ensure uninterrupted use of AyaNova" + (ko.isLite ? " Lite" : "") + ". \r\n\r\n"); + "mail and processing time to ensure uninterrupted use of AyaNova. \r\n\r\n"); } sb.Append("Registered to: "); - sb.Append(ko.registeredTo); + sb.Append(l.RegTo); sb.Append("\r\n"); //case 3233 sb.Append("Fetch address: "); - sb.Append(ko.emailAddress); + sb.Append(l.FetchEmail); sb.Append("\r\n"); sb.Append("Fetch code: "); - sb.Append(ko.fetchCode); + sb.Append(l.FetchCode); sb.Append("\r\n"); sb.Append("Scheduleable resources: "); - switch (ko.users) + switch (l.Users) { case 1: sb.AppendLine("1"); @@ -238,13 +238,13 @@ namespace Sockeye.Biz break; } - sb.AppendLine("Support and updates until: " + DateUtil.EpochToString(ko.supportExpiresDate) + "\r\n"); - - if (_plugins.Count > 0) + sb.AppendLine($"Support and updates until: {l.MaintenanceExpire}\r\n"); + var Plugs=LicenseToPluginsArray(l); + if (Plugs.Count > 0) { sb.Append("\r\n"); sb.Append("Plugins:\r\n"); - foreach (KeyValuePair kv in _plugins) + foreach (KeyValuePair kv in Plugs) { sb.Append("\t"); sb.Append(kv.Key); @@ -279,154 +279,183 @@ namespace Sockeye.Biz } + private static Dictionary LicenseToPluginsArray(License l) + { + Dictionary Plugs = new Dictionary(); + if (l.MBI) + Plugs.Add(PLUGIN_MBI_KEY, (DateTime)l.MBIExpires); + + if (l.WBI) + Plugs.Add(PLUGIN_WBI_KEY, (DateTime)l.WBIExpires); + + if (l.QBI) + Plugs.Add(PLUGIN_QBI_KEY, (DateTime)l.QBIExpires); + + if (l.QBOI) + Plugs.Add(PLUGIN_QBOI_KEY, (DateTime)l.QBOIExpires); + + if (l.PTI) + Plugs.Add(PLUGIN_PTI_KEY, (DateTime)l.PTIExpires); + + if (l.QuickNotification) + Plugs.Add(PLUGIN_QUICK_NOTIFICATION_KEY, (DateTime)l.QuickNotificationExpires); + + if (l.ExportToXLS) + Plugs.Add(PLUGIN_EXPORT_TO_XLS_KEY, (DateTime)l.ExportToXLSExpires); + + if (l.OutlookSchedule) + Plugs.Add(PLUGIN_OUTLOOK_SCHEDULE_KEY, (DateTime)l.OutlookScheduleExpires); + + if (l.OLI) + Plugs.Add(PLUGIN_OLI_KEY, (DateTime)l.OLIExpires); + + if (l.ImportExportCSVDuplicate) + Plugs.Add(PLUGIN_IMPORT_EXPORT_CSV_DUPLICATE_KEY, (DateTime)l.ImportExportCSVDuplicateExpires); + + if (l.RI) + Plugs.Add(PLUGIN_RI_KEY, (DateTime)l.RIExpires); + + return Plugs; + } /// /// Generate keycode based on passed in data /// This is called by both regular and trial license key routes /// /// - private static string genKey(License l) + private static void genKey(License l) { - _plugins = new Dictionary(); - - try + StringBuilder sbKey = new StringBuilder(); + StringWriter sw = new StringWriter(sbKey); + l.FetchCode = GenFetchCode(); + using (Newtonsoft.Json.JsonWriter w = new Newtonsoft.Json.JsonTextWriter(sw)) { + w.Formatting = Newtonsoft.Json.Formatting.Indented; + //outer object start + w.WriteStartObject(); + w.WritePropertyName("AyaNovaLicenseKey"); - StringBuilder sbKey = new StringBuilder(); - StringWriter sw = new StringWriter(sbKey); + w.WriteStartObject();//start of key object + + w.WritePropertyName("SchemaVersion"); + w.WriteValue("7"); + + //stamp a unique value in the key so it can be revoked later + //used to use the digest value of the key for this with xml key + //whole unix timestamp seconds but kept as a double to work beyond 2038 + w.WritePropertyName("Id"); + var vv = Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds); + string sId = vv.ToString(); + if (sId.Contains(",")) + sId = sId.Split('.')[0]; + w.WriteValue(sId); + + w.WritePropertyName("Created"); + w.WriteValue(System.DateTime.Now); + + w.WritePropertyName("Sub"); + w.WriteValue("true"); + + w.WritePropertyName("RegisteredTo"); + w.WriteValue(l.RegTo); + + //case 3233 + w.WritePropertyName("EmailAddress"); + w.WriteValue(l.FetchEmail); + + w.WritePropertyName("FetchCode"); + + w.WriteValue(l.FetchCode); + + //case 3187 - Source here + //rockfish + w.WritePropertyName("Source"); + w.WriteValue(StringUtil.ToHex("RFID" + "420")); - l.FetchCode = GenFetchCode(); + w.WritePropertyName("InstallableUntil"); + w.WriteValue(l.MaintenanceExpire); - using (Newtonsoft.Json.JsonWriter w = new Newtonsoft.Json.JsonTextWriter(sw)) + w.WritePropertyName("TotalScheduleableUsers"); + w.WriteValue(l.Users.ToString());//Needs to be a string to match rockfish format + + w.WritePropertyName("Expires"); + w.WriteValue(l.MaintenanceExpire); + + if (l.LicenseExpire != null) { - w.Formatting = Newtonsoft.Json.Formatting.Indented; + w.WritePropertyName("LockDate"); + w.WriteValue(l.LicenseExpire); - //outer object start - w.WriteStartObject(); - w.WritePropertyName("AyaNovaLicenseKey"); + } - w.WriteStartObject();//start of key object + w.WritePropertyName("RequestedTrial"); + w.WriteValue(l.TrialMode.ToString()); - w.WritePropertyName("SchemaVersion"); - w.WriteValue("7"); + //PLUGINS + w.WritePropertyName("Plugins"); + w.WriteStartObject();//start of key object + w.WritePropertyName("Plugin"); + w.WriteStartArray(); - //stamp a unique value in the key so it can be revoked later - //used to use the digest value of the key for this with xml key - //whole unix timestamp seconds but kept as a double to work beyond 2038 - w.WritePropertyName("Id"); - var vv = Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds); - string sId = vv.ToString(); - if (sId.Contains(",")) - sId = sId.Split('.')[0]; - w.WriteValue(sId); + if (l.MBI) + AddLicensePlugin(w, PLUGIN_MBI_KEY, l.MBIExpires); - w.WritePropertyName("Created"); - w.WriteValue(System.DateTime.Now); + if (l.WBI) + AddLicensePlugin(w, PLUGIN_WBI_KEY, l.WBIExpires); - w.WritePropertyName("Sub"); - w.WriteValue("true"); + if (l.QBI) + AddLicensePlugin(w, PLUGIN_QBI_KEY, l.QBIExpires); - w.WritePropertyName("RegisteredTo"); - w.WriteValue(l.RegTo); + if (l.QBOI) + AddLicensePlugin(w, PLUGIN_QBOI_KEY, l.QBOIExpires); - //case 3233 - w.WritePropertyName("EmailAddress"); - w.WriteValue(l.FetchEmail); + if (l.PTI) + AddLicensePlugin(w, PLUGIN_PTI_KEY, l.PTIExpires); - w.WritePropertyName("FetchCode"); + if (l.QuickNotification) + AddLicensePlugin(w, PLUGIN_QUICK_NOTIFICATION_KEY, l.QuickNotificationExpires); - w.WriteValue(l.FetchCode); + if (l.ExportToXLS) + AddLicensePlugin(w, PLUGIN_EXPORT_TO_XLS_KEY, l.ExportToXLSExpires); - //case 3187 - Source here - //rockfish - w.WritePropertyName("Source"); - w.WriteValue(StringUtil.ToHex("RFID" + "420")); + if (l.OutlookSchedule) + AddLicensePlugin(w, PLUGIN_OUTLOOK_SCHEDULE_KEY, l.OutlookScheduleExpires); + + if (l.OLI) + AddLicensePlugin(w, PLUGIN_OLI_KEY, l.OLIExpires); + + if (l.ImportExportCSVDuplicate) + AddLicensePlugin(w, PLUGIN_IMPORT_EXPORT_CSV_DUPLICATE_KEY, l.ImportExportCSVDuplicateExpires); + + if (l.RI) + AddLicensePlugin(w, PLUGIN_RI_KEY, l.RIExpires); + + //end of plugins array + w.WriteEnd(); + + //end of plugins object + w.WriteEndObject(); + + //end of AyaNova/AyaNovaLite key object + w.WriteEndObject(); + + //close outer 'wrapper' object brace } + w.WriteEndObject(); + + }//end of using statement - w.WritePropertyName("InstallableUntil"); - w.WriteValue(l.MaintenanceExpire); + // ## CALCULATE SIGNATURE - w.WritePropertyName("TotalScheduleableUsers"); - w.WriteValue(l.Users.ToString());//Needs to be a string to match rockfish format - - w.WritePropertyName("Expires"); - w.WriteValue(l.MaintenanceExpire); - - if (l.LicenseExpire!=null) - { - w.WritePropertyName("LockDate"); - w.WriteValue(l.LicenseExpire); - - } - - w.WritePropertyName("RequestedTrial"); - w.WriteValue(l.TrialMode.ToString()); - - //PLUGINS - w.WritePropertyName("Plugins"); - w.WriteStartObject();//start of key object - w.WritePropertyName("Plugin"); - w.WriteStartArray(); - - if (l.MBI) - AddLicensePlugin(w, PLUGIN_MBI_KEY, l.MBIExpires); - - if (l.WBI) - AddLicensePlugin(w, PLUGIN_WBI_KEY, l.WBIExpires); - - if (l.QBI) - AddLicensePlugin(w, PLUGIN_QBI_KEY, l.QBIExpires); - - if (l.QBOI) - AddLicensePlugin(w, PLUGIN_QBOI_KEY, l.QBOIExpires); - - if (l.PTI) - AddLicensePlugin(w, PLUGIN_PTI_KEY, l.PTIExpires); - - if (l.QuickNotification) - AddLicensePlugin(w, PLUGIN_QUICK_NOTIFICATION_KEY, l.QuickNotificationExpires); - - if (l.ExportToXLS) - AddLicensePlugin(w, PLUGIN_EXPORT_TO_XLS_KEY, l.ExportToXLSExpires); - - if (l.OutlookSchedule) - AddLicensePlugin(w, PLUGIN_OUTLOOK_SCHEDULE_KEY, l.OutlookScheduleExpires); - - if (l.OLI) - AddLicensePlugin(w, PLUGIN_OLI_KEY, l.OLIExpires); - - if (l.ImportExportCSVDuplicate) - AddLicensePlugin(w, PLUGIN_IMPORT_EXPORT_CSV_DUPLICATE_KEY, l.ImportExportCSVDuplicateExpires); - - if (l.RI) - AddLicensePlugin(w, PLUGIN_RI_KEY, l.RIExpires); - - //end of plugins array - w.WriteEnd(); - - //end of plugins object - w.WriteEndObject(); - - //end of AyaNova/AyaNovaLite key object - w.WriteEndObject(); - - //close outer 'wrapper' object brace } - w.WriteEndObject(); - - }//end of using statement + //GET JSON as a string with whitespace stripped outside of delimited strings + //http://stackoverflow.com/questions/8913138/minify-indented-json-string-in-net + string keyNoWS = System.Text.RegularExpressions.Regex.Replace(sbKey.ToString(), "(\"(?:[^\"\\\\]|\\\\.)*\")|\\s+", "$1"); - // ## CALCULATE SIGNATURE - - //GET JSON as a string with whitespace stripped outside of delimited strings - //http://stackoverflow.com/questions/8913138/minify-indented-json-string-in-net - string keyNoWS = System.Text.RegularExpressions.Regex.Replace(sbKey.ToString(), "(\"(?:[^\"\\\\]|\\\\.)*\")|\\s+", "$1"); - - - //**** Note this is our real 2016 private key - var privatePEM = @"-----BEGIN RSA PRIVATE KEY----- + //**** Note this is our real 2016 private key + var privatePEM = @"-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAz7wrvLDcKVMZ31HFGBnLWL08IodYIV5VJkKy1Z0n2snprhSi u3izxTyz+SLpftvKHJpky027ii7l/pL9Bo3JcjU5rKrxXavnE7TuYPjXn16dNLd0 K/ERSU+pXLmUaVN0nUWuGuUMoGJMEXoulS6pJiG11yu3BM9fL2Nbj0C6a+UwzEHF @@ -454,44 +483,31 @@ CYf6emoB4mLXFPvAmnsalkhN2iB29hUZCXXSUjpKZrpijL54Wdu2S6ynm7aT97NF oArP0E2Vbow3JMxq/oeXmHbrLMLQfYyXwFmciLFigOtkd45bfHdrbA== -----END RSA PRIVATE KEY-----"; - PemReader pr = new PemReader(new StringReader(privatePEM)); - AsymmetricCipherKeyPair keys = (AsymmetricCipherKeyPair)pr.ReadObject(); - var encoder = new UTF8Encoding(false, true); - var inputData = encoder.GetBytes(keyNoWS); - var signer = SignerUtilities.GetSigner("SHA256WITHRSA"); - signer.Init(true, keys.Private); - signer.BlockUpdate(inputData, 0, inputData.Length); - var sign = signer.GenerateSignature(); - var signature = Convert.ToBase64String(sign); + PemReader pr = new PemReader(new StringReader(privatePEM)); + AsymmetricCipherKeyPair keys = (AsymmetricCipherKeyPair)pr.ReadObject(); + var encoder = new UTF8Encoding(false, true); + var inputData = encoder.GetBytes(keyNoWS); + var signer = SignerUtilities.GetSigner("SHA256WITHRSA"); + signer.Init(true, keys.Private); + signer.BlockUpdate(inputData, 0, inputData.Length); + var sign = signer.GenerateSignature(); + var signature = Convert.ToBase64String(sign); + + + System.Text.StringBuilder sbOut = new StringBuilder(); + sbOut.AppendLine("[KEY"); + sbOut.AppendLine(sbKey.ToString()); + sbOut.AppendLine("KEY]"); + sbOut.AppendLine("[SIGNATURE"); + sbOut.AppendLine(signature); + sbOut.AppendLine("SIGNATURE]"); + + l.Key = sbOut.ToString(); - System.Text.StringBuilder sbOut = new StringBuilder(); - sbOut.AppendLine("[KEY"); - sbOut.AppendLine(sbKey.ToString()); - sbOut.AppendLine("KEY]"); - sbOut.AppendLine("[SIGNATURE"); - sbOut.AppendLine(signature); - sbOut.AppendLine("SIGNATURE]"); - // //case 3233 insert into db - // License l = new License(); - // l.DtCreated = DateUtil.NowAsEpoch(); - // l.Code = ko.fetchCode; - // l.CustomerId = ko.customerId; - // l.Email = ko.emailAddress.ToLowerInvariant(); - // l.Key = sbOut.ToString(); - // l.RegTo = ko.registeredTo; - // ct.License.Add(l); - // ct.SaveChanges(); - - return sbOut.ToString(); - } - catch (Exception ex) - { - return (ex.Message); - } } @@ -499,9 +515,7 @@ oArP0E2Vbow3JMxq/oeXmHbrLMLQfYyXwFmciLFigOtkd45bfHdrbA== private static void AddLicensePlugin(Newtonsoft.Json.JsonWriter w, string pluginName, DateTime? pluginExpires) { - //this dictionary is used by the additional message code to - //make the human readable portion of the license - _plugins.Add(pluginName, (DateTime)pluginExpires); + //this is adding it to the actual key w.WriteStartObject();