Nav apraksta
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

ObfuscationGenerator.cs 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using UnityEngine;
  5. namespace UnityEditor.Purchasing
  6. {
  7. class ObfuscationGenerator
  8. {
  9. const string m_GeneratedCredentialsTemplateFilename = "IAPGeneratedCredentials.cs.template";
  10. const string m_GeneratedCredentialsTemplateFilenameNoExtension = "IAPGeneratedCredentials.cs";
  11. const string k_AppleCertPath = "Packages/com.unity.purchasing/Editor/AppleIncRootCertificate.cer";
  12. const string k_AppleStoreKitTestCertPath = "Packages/com.unity.purchasing/Editor/StoreKitTestCertificate.cer";
  13. const string k_AppleClassIncompleteErr = "Invalid Apple Root Certificate";
  14. const string k_AppleStoreKitTestClassIncompleteErr = "Invalid Apple StoreKit Test Certificate";
  15. internal static string ObfuscateAppleSecrets()
  16. {
  17. var appleError = WriteObfuscatedAppleClassAsAsset();
  18. AssetDatabase.Refresh();
  19. return appleError;
  20. }
  21. internal static string ObfuscateGoogleSecrets(string googlePlayPublicKey)
  22. {
  23. var googleError = WriteObfuscatedGooglePlayClassAsAsset(googlePlayPublicKey);
  24. AssetDatabase.Refresh();
  25. return googleError;
  26. }
  27. /// <summary>
  28. /// Generates specified obfuscated class files.
  29. /// </summary>
  30. internal static void ObfuscateSecrets(bool includeGoogle, ref string appleError, ref string googleError, string googlePlayPublicKey)
  31. {
  32. try
  33. {
  34. // First things first! Obfuscate! XHTLOA!
  35. appleError = WriteObfuscatedAppleClassAsAsset();
  36. if (includeGoogle)
  37. {
  38. googleError = WriteObfuscatedGooglePlayClassAsAsset(googlePlayPublicKey);
  39. }
  40. }
  41. catch (Exception e)
  42. {
  43. Debug.LogWarning(e.StackTrace);
  44. }
  45. // Ensure all the Tangle classes exist, even if they were not generated at this time.
  46. if (!DoesGooglePlayTangleClassExist())
  47. {
  48. try
  49. {
  50. WriteObfuscatedClassAsAsset(TangleFileConsts.k_GooglePlayClassPrefix, 0, new int[0], new byte[0], false);
  51. }
  52. catch (Exception e)
  53. {
  54. Debug.LogWarning(e.StackTrace);
  55. }
  56. }
  57. AssetDatabase.Refresh();
  58. }
  59. static string WriteObfuscatedAppleClassAsAsset()
  60. {
  61. var err = WriteObfuscatedAppleClassAsAsset(k_AppleCertPath, k_AppleClassIncompleteErr, TangleFileConsts.k_AppleClassPrefix);
  62. if (err == null)
  63. {
  64. err = WriteObfuscatedAppleClassAsAsset(k_AppleStoreKitTestCertPath, k_AppleStoreKitTestClassIncompleteErr, TangleFileConsts.k_AppleStoreKitTestClassPrefix);
  65. }
  66. return err;
  67. }
  68. static string WriteObfuscatedAppleClassAsAsset(string certPath, string classIncompleteErr, string classPrefix)
  69. {
  70. string appleError = null;
  71. var key = 0;
  72. var order = new int[0];
  73. var tangled = new byte[0];
  74. try
  75. {
  76. var bytes = File.ReadAllBytes(certPath);
  77. order = new int[bytes.Length / 20 + 1];
  78. // TODO: Integrate with upgraded Tangle!
  79. tangled = TangleObfuscator.Obfuscate(bytes, order, out key);
  80. }
  81. catch (Exception e)
  82. {
  83. Debug.LogWarning($"{classIncompleteErr}. Generating incomplete credentials file. " + e);
  84. appleError = $" {classIncompleteErr}";
  85. }
  86. WriteObfuscatedClassAsAsset(classPrefix, key, order, tangled, tangled.Length != 0);
  87. return appleError;
  88. }
  89. static string WriteObfuscatedGooglePlayClassAsAsset(string googlePlayPublicKey)
  90. {
  91. string googleError = null;
  92. var key = 0;
  93. var order = new int[0];
  94. var tangled = new byte[0];
  95. try
  96. {
  97. var bytes = Convert.FromBase64String(googlePlayPublicKey);
  98. order = new int[bytes.Length / 20 + 1];
  99. tangled = TangleObfuscator.Obfuscate(bytes, order, out key);
  100. }
  101. catch (Exception e)
  102. {
  103. Debug.LogWarning("Invalid Google Play Public Key. Generating incomplete credentials file. " + e);
  104. googleError =
  105. " The Google Play License Key is invalid. GooglePlayTangle was generated with incomplete credentials.";
  106. }
  107. WriteObfuscatedClassAsAsset(TangleFileConsts.k_GooglePlayClassPrefix, key, order, tangled, tangled.Length != 0);
  108. return googleError;
  109. }
  110. static string FullPathForTangleClass(string classnamePrefix)
  111. {
  112. return Path.Combine(TangleFileConsts.k_OutputPath, string.Format($"{classnamePrefix}{TangleFileConsts.k_ObfuscationClassSuffix}"));
  113. }
  114. internal static bool DoesAppleTangleClassExist()
  115. {
  116. return ObfuscatedClassExists(TangleFileConsts.k_AppleClassPrefix) &&
  117. ObfuscatedClassExists(TangleFileConsts.k_AppleStoreKitTestClassPrefix);
  118. }
  119. internal static bool DoesGooglePlayTangleClassExist()
  120. {
  121. return ObfuscatedClassExists(TangleFileConsts.k_GooglePlayClassPrefix);
  122. }
  123. static bool ObfuscatedClassExists(string classnamePrefix)
  124. {
  125. return File.Exists(FullPathForTangleClass(classnamePrefix));
  126. }
  127. static void WriteObfuscatedClassAsAsset(string classnamePrefix, int key, int[] order, byte[] data, bool populated)
  128. {
  129. var substitutionDictionary = new Dictionary<string, string>()
  130. {
  131. {"{NAME}", classnamePrefix.ToString()},
  132. {"{KEY}", key.ToString()},
  133. {"{ORDER}", String.Format("{0}",String.Join(",", Array.ConvertAll(order, i => i.ToString())))},
  134. {"{DATA}", Convert.ToBase64String(data)},
  135. {"{POPULATED}", populated.ToString().ToLowerInvariant()} // Defaults to XML-friendly values
  136. };
  137. var templateText = LoadTemplateText(out var templateRelativePath);
  138. if (templateText != null)
  139. {
  140. var outfileText = templateText;
  141. // Apply the parameters to the template
  142. foreach (var pair in substitutionDictionary)
  143. {
  144. outfileText = outfileText.Replace(pair.Key, pair.Value);
  145. }
  146. Directory.CreateDirectory(TangleFileConsts.k_OutputPath);
  147. File.WriteAllText(FullPathForTangleClass(classnamePrefix), outfileText);
  148. }
  149. }
  150. /// <summary>
  151. /// Loads the template file.
  152. /// </summary>
  153. /// <returns>The template file's text.</returns>
  154. /// <param name="templateRelativePath">Relative Assets/ path to template file.</param>
  155. static string LoadTemplateText(out string templateRelativePath)
  156. {
  157. var assetGUIDs =
  158. AssetDatabase.FindAssets(m_GeneratedCredentialsTemplateFilenameNoExtension);
  159. string templateGUID = null;
  160. templateRelativePath = null;
  161. if (assetGUIDs.Length > 0)
  162. {
  163. templateGUID = assetGUIDs[0];
  164. }
  165. else
  166. {
  167. Debug.LogError(String.Format("Could not find template \"{0}\"",
  168. m_GeneratedCredentialsTemplateFilename));
  169. }
  170. string templateText = null;
  171. if (templateGUID != null)
  172. {
  173. templateRelativePath = AssetDatabase.GUIDToAssetPath(templateGUID);
  174. var templateAbsolutePath =
  175. Path.GetDirectoryName(Application.dataPath)
  176. + Path.DirectorySeparatorChar
  177. + templateRelativePath;
  178. templateText = File.ReadAllText(templateAbsolutePath);
  179. }
  180. return templateText;
  181. }
  182. }
  183. }