MacUtilities.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using System.Globalization;
  6. using System.Security.Cryptography;
  7. using BestHTTP.PlatformSupport.Memory;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Iana;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Misc;
  11. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
  12. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  13. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Rosstandart;
  14. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  15. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
  16. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
  17. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Paddings;
  18. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  19. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Security
  20. {
  21. /// <remarks>
  22. /// Utility class for creating HMac object from their names/Oids
  23. /// </remarks>
  24. public sealed class MacUtilities
  25. {
  26. private MacUtilities()
  27. {
  28. }
  29. private static readonly IDictionary algorithms = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
  30. //private static readonly IDictionary oids = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
  31. static MacUtilities()
  32. {
  33. algorithms[IanaObjectIdentifiers.HmacMD5.Id] = "HMAC-MD5";
  34. algorithms[IanaObjectIdentifiers.HmacRipeMD160.Id] = "HMAC-RIPEMD160";
  35. algorithms[IanaObjectIdentifiers.HmacSha1.Id] = "HMAC-SHA1";
  36. algorithms[IanaObjectIdentifiers.HmacTiger.Id] = "HMAC-TIGER";
  37. algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "HMAC-SHA1";
  38. algorithms[MiscObjectIdentifiers.HMAC_SHA1.Id] = "HMAC-SHA1";
  39. algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "HMAC-SHA224";
  40. algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "HMAC-SHA256";
  41. algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "HMAC-SHA384";
  42. algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "HMAC-SHA512";
  43. algorithms[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "HMAC-SHA3-224";
  44. algorithms[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "HMAC-SHA3-256";
  45. algorithms[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "HMAC-SHA3-384";
  46. algorithms[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "HMAC-SHA3-512";
  47. algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256.Id] = "HMAC-GOST3411-2012-256";
  48. algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512.Id] = "HMAC-GOST3411-2012-512";
  49. // TODO AESMAC?
  50. algorithms["DES"] = "DESMAC";
  51. algorithms["DES/CFB8"] = "DESMAC/CFB8";
  52. algorithms["DES64"] = "DESMAC64";
  53. algorithms["DESEDE"] = "DESEDEMAC";
  54. algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDEMAC";
  55. algorithms["DESEDE/CFB8"] = "DESEDEMAC/CFB8";
  56. algorithms["DESISO9797MAC"] = "DESWITHISO9797";
  57. algorithms["DESEDE64"] = "DESEDEMAC64";
  58. algorithms["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
  59. algorithms["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
  60. algorithms["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
  61. algorithms["ISO9797ALG3"] = "ISO9797ALG3MAC";
  62. algorithms["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING";
  63. algorithms["SKIPJACK"] = "SKIPJACKMAC";
  64. algorithms["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8";
  65. algorithms["IDEA"] = "IDEAMAC";
  66. algorithms["IDEA/CFB8"] = "IDEAMAC/CFB8";
  67. algorithms["RC2"] = "RC2MAC";
  68. algorithms["RC2/CFB8"] = "RC2MAC/CFB8";
  69. algorithms["RC5"] = "RC5MAC";
  70. algorithms["RC5/CFB8"] = "RC5MAC/CFB8";
  71. algorithms["GOST28147"] = "GOST28147MAC";
  72. algorithms["VMPC"] = "VMPCMAC";
  73. algorithms["VMPC-MAC"] = "VMPCMAC";
  74. algorithms["SIPHASH"] = "SIPHASH-2-4";
  75. algorithms["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1";
  76. algorithms["1.3.14.3.2.26"] = "PBEWITHHMACSHA1";
  77. }
  78. // /// <summary>
  79. // /// Returns a ObjectIdentifier for a given digest mechanism.
  80. // /// </summary>
  81. // /// <param name="mechanism">A string representation of the digest meanism.</param>
  82. // /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
  83. // public static DerObjectIdentifier GetObjectIdentifier(
  84. // string mechanism)
  85. // {
  86. // mechanism = (string) algorithms[BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(mechanism)];
  87. //
  88. // if (mechanism != null)
  89. // {
  90. // return (DerObjectIdentifier)oids[mechanism];
  91. // }
  92. //
  93. // return null;
  94. // }
  95. // public static ICollection Algorithms
  96. // {
  97. // get { return oids.Keys; }
  98. // }
  99. public static IMac GetMac(
  100. DerObjectIdentifier id)
  101. {
  102. return GetMac(id.Id);
  103. }
  104. public static IMac GetMac(
  105. string algorithm)
  106. {
  107. string upper = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm);
  108. string mechanism = (string) algorithms[upper];
  109. if (mechanism == null)
  110. {
  111. mechanism = upper;
  112. }
  113. if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "PBEWITH"))
  114. {
  115. mechanism = mechanism.Substring("PBEWITH".Length);
  116. }
  117. if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC"))
  118. {
  119. string digestName;
  120. if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC-") || BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC/"))
  121. {
  122. digestName = mechanism.Substring(5);
  123. }
  124. else
  125. {
  126. digestName = mechanism.Substring(4);
  127. }
  128. return new HMac(DigestUtilities.GetDigest(digestName));
  129. }
  130. if (mechanism == "AESCMAC")
  131. {
  132. return new CMac(new AesEngine());
  133. }
  134. if (mechanism == "DESMAC")
  135. {
  136. return new CbcBlockCipherMac(new DesEngine());
  137. }
  138. if (mechanism == "DESMAC/CFB8")
  139. {
  140. return new CfbBlockCipherMac(new DesEngine());
  141. }
  142. if (mechanism == "DESMAC64")
  143. {
  144. return new CbcBlockCipherMac(new DesEngine(), 64);
  145. }
  146. if (mechanism == "DESEDECMAC")
  147. {
  148. return new CMac(new DesEdeEngine());
  149. }
  150. if (mechanism == "DESEDEMAC")
  151. {
  152. return new CbcBlockCipherMac(new DesEdeEngine());
  153. }
  154. if (mechanism == "DESEDEMAC/CFB8")
  155. {
  156. return new CfbBlockCipherMac(new DesEdeEngine());
  157. }
  158. if (mechanism == "DESEDEMAC64")
  159. {
  160. return new CbcBlockCipherMac(new DesEdeEngine(), 64);
  161. }
  162. if (mechanism == "DESEDEMAC64WITHISO7816-4PADDING")
  163. {
  164. return new CbcBlockCipherMac(new DesEdeEngine(), 64, new ISO7816d4Padding());
  165. }
  166. if (mechanism == "DESWITHISO9797"
  167. || mechanism == "ISO9797ALG3MAC")
  168. {
  169. return new ISO9797Alg3Mac(new DesEngine());
  170. }
  171. if (mechanism == "ISO9797ALG3WITHISO7816-4PADDING")
  172. {
  173. return new ISO9797Alg3Mac(new DesEngine(), new ISO7816d4Padding());
  174. }
  175. if (mechanism == "SKIPJACKMAC")
  176. {
  177. return new CbcBlockCipherMac(new SkipjackEngine());
  178. }
  179. if (mechanism == "SKIPJACKMAC/CFB8")
  180. {
  181. return new CfbBlockCipherMac(new SkipjackEngine());
  182. }
  183. if (mechanism == "IDEAMAC")
  184. {
  185. return new CbcBlockCipherMac(new IdeaEngine());
  186. }
  187. if (mechanism == "IDEAMAC/CFB8")
  188. {
  189. return new CfbBlockCipherMac(new IdeaEngine());
  190. }
  191. if (mechanism == "RC2MAC")
  192. {
  193. return new CbcBlockCipherMac(new RC2Engine());
  194. }
  195. if (mechanism == "RC2MAC/CFB8")
  196. {
  197. return new CfbBlockCipherMac(new RC2Engine());
  198. }
  199. if (mechanism == "RC5MAC")
  200. {
  201. return new CbcBlockCipherMac(new RC532Engine());
  202. }
  203. if (mechanism == "RC5MAC/CFB8")
  204. {
  205. return new CfbBlockCipherMac(new RC532Engine());
  206. }
  207. if (mechanism == "GOST28147MAC")
  208. {
  209. return new Gost28147Mac();
  210. }
  211. if (mechanism == "VMPCMAC")
  212. {
  213. return new VmpcMac();
  214. }
  215. if (mechanism == "SIPHASH-2-4")
  216. {
  217. return new SipHash();
  218. }
  219. throw new SecurityUtilityException("Mac " + mechanism + " not recognised.");
  220. }
  221. public static string GetAlgorithmName(
  222. DerObjectIdentifier oid)
  223. {
  224. return (string) algorithms[oid.Id];
  225. }
  226. public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input)
  227. {
  228. IMac mac = GetMac(algorithm);
  229. mac.Init(cp);
  230. mac.BlockUpdate(input, 0, input.Length);
  231. return DoFinal(mac);
  232. }
  233. public static byte[] DoFinal(IMac mac)
  234. {
  235. byte[] b = new byte[mac.GetMacSize()];
  236. mac.DoFinal(b, 0);
  237. return b;
  238. }
  239. public static BufferSegment DoFinalOptimized(IMac mac)
  240. {
  241. int length = mac.GetMacSize();
  242. byte[] b = BufferPool.Get(length, true);
  243. mac.DoFinal(b, 0);
  244. return new BufferSegment(b, 0, length);
  245. }
  246. public static byte[] DoFinal(IMac mac, byte[] input)
  247. {
  248. mac.BlockUpdate(input, 0, input.Length);
  249. return DoFinal(mac);
  250. }
  251. }
  252. }
  253. #pragma warning restore
  254. #endif