ParameterUtilities.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.CryptoPro;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Kisa;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Misc;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Ntt;
  11. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Oiw;
  12. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  13. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  14. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  15. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  16. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Security
  17. {
  18. public sealed class ParameterUtilities
  19. {
  20. private ParameterUtilities()
  21. {
  22. }
  23. private static readonly IDictionary algorithms = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
  24. private static readonly IDictionary basicIVSizes = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
  25. static ParameterUtilities()
  26. {
  27. AddAlgorithm("AES",
  28. "AESWRAP");
  29. AddAlgorithm("AES128",
  30. "2.16.840.1.101.3.4.2",
  31. NistObjectIdentifiers.IdAes128Cbc,
  32. NistObjectIdentifiers.IdAes128Cfb,
  33. NistObjectIdentifiers.IdAes128Ecb,
  34. NistObjectIdentifiers.IdAes128Ofb,
  35. NistObjectIdentifiers.IdAes128Wrap);
  36. AddAlgorithm("AES192",
  37. "2.16.840.1.101.3.4.22",
  38. NistObjectIdentifiers.IdAes192Cbc,
  39. NistObjectIdentifiers.IdAes192Cfb,
  40. NistObjectIdentifiers.IdAes192Ecb,
  41. NistObjectIdentifiers.IdAes192Ofb,
  42. NistObjectIdentifiers.IdAes192Wrap);
  43. AddAlgorithm("AES256",
  44. "2.16.840.1.101.3.4.42",
  45. NistObjectIdentifiers.IdAes256Cbc,
  46. NistObjectIdentifiers.IdAes256Cfb,
  47. NistObjectIdentifiers.IdAes256Ecb,
  48. NistObjectIdentifiers.IdAes256Ofb,
  49. NistObjectIdentifiers.IdAes256Wrap);
  50. AddAlgorithm("BLOWFISH",
  51. "1.3.6.1.4.1.3029.1.2");
  52. AddAlgorithm("CAMELLIA",
  53. "CAMELLIAWRAP");
  54. AddAlgorithm("CAMELLIA128",
  55. NttObjectIdentifiers.IdCamellia128Cbc,
  56. NttObjectIdentifiers.IdCamellia128Wrap);
  57. AddAlgorithm("CAMELLIA192",
  58. NttObjectIdentifiers.IdCamellia192Cbc,
  59. NttObjectIdentifiers.IdCamellia192Wrap);
  60. AddAlgorithm("CAMELLIA256",
  61. NttObjectIdentifiers.IdCamellia256Cbc,
  62. NttObjectIdentifiers.IdCamellia256Wrap);
  63. AddAlgorithm("CAST5",
  64. "1.2.840.113533.7.66.10");
  65. AddAlgorithm("CAST6");
  66. AddAlgorithm("DES",
  67. OiwObjectIdentifiers.DesCbc,
  68. OiwObjectIdentifiers.DesCfb,
  69. OiwObjectIdentifiers.DesEcb,
  70. OiwObjectIdentifiers.DesOfb);
  71. AddAlgorithm("DESEDE",
  72. "DESEDEWRAP",
  73. "TDEA",
  74. OiwObjectIdentifiers.DesEde,
  75. PkcsObjectIdentifiers.IdAlgCms3DesWrap);
  76. AddAlgorithm("DESEDE3",
  77. PkcsObjectIdentifiers.DesEde3Cbc);
  78. AddAlgorithm("GOST28147",
  79. "GOST",
  80. "GOST-28147",
  81. CryptoProObjectIdentifiers.GostR28147Cbc);
  82. AddAlgorithm("HC128");
  83. AddAlgorithm("HC256");
  84. AddAlgorithm("IDEA",
  85. "1.3.6.1.4.1.188.7.1.1.2");
  86. AddAlgorithm("NOEKEON");
  87. AddAlgorithm("RC2",
  88. PkcsObjectIdentifiers.RC2Cbc,
  89. PkcsObjectIdentifiers.IdAlgCmsRC2Wrap);
  90. AddAlgorithm("RC4",
  91. "ARC4",
  92. "1.2.840.113549.3.4");
  93. AddAlgorithm("RC5",
  94. "RC5-32");
  95. AddAlgorithm("RC5-64");
  96. AddAlgorithm("RC6");
  97. AddAlgorithm("RIJNDAEL");
  98. AddAlgorithm("SALSA20");
  99. AddAlgorithm("SEED",
  100. KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap,
  101. KisaObjectIdentifiers.IdSeedCbc);
  102. AddAlgorithm("SERPENT");
  103. AddAlgorithm("SKIPJACK");
  104. AddAlgorithm("SM4");
  105. AddAlgorithm("TEA");
  106. AddAlgorithm("THREEFISH-256");
  107. AddAlgorithm("THREEFISH-512");
  108. AddAlgorithm("THREEFISH-1024");
  109. AddAlgorithm("TNEPRES");
  110. AddAlgorithm("TWOFISH");
  111. AddAlgorithm("VMPC");
  112. AddAlgorithm("VMPC-KSA3");
  113. AddAlgorithm("XTEA");
  114. AddBasicIVSizeEntries(8, "BLOWFISH", "DES", "DESEDE", "DESEDE3");
  115. AddBasicIVSizeEntries(16, "AES", "AES128", "AES192", "AES256",
  116. "CAMELLIA", "CAMELLIA128", "CAMELLIA192", "CAMELLIA256",
  117. "NOEKEON", "SEED", "SM4");
  118. // TODO These algorithms support an IV
  119. // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them
  120. // "RIJNDAEL", "SKIPJACK", "TWOFISH"
  121. }
  122. private static void AddAlgorithm(
  123. string canonicalName,
  124. params object[] aliases)
  125. {
  126. algorithms[canonicalName] = canonicalName;
  127. foreach (object alias in aliases)
  128. {
  129. algorithms[alias.ToString()] = canonicalName;
  130. }
  131. }
  132. private static void AddBasicIVSizeEntries(int size, params string[] algorithms)
  133. {
  134. foreach (string algorithm in algorithms)
  135. {
  136. basicIVSizes.Add(algorithm, size);
  137. }
  138. }
  139. public static string GetCanonicalAlgorithmName(
  140. string algorithm)
  141. {
  142. return (string) algorithms[BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm)];
  143. }
  144. public static KeyParameter CreateKeyParameter(
  145. DerObjectIdentifier algOid,
  146. byte[] keyBytes)
  147. {
  148. return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length);
  149. }
  150. public static KeyParameter CreateKeyParameter(
  151. string algorithm,
  152. byte[] keyBytes)
  153. {
  154. return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length);
  155. }
  156. public static KeyParameter CreateKeyParameter(
  157. DerObjectIdentifier algOid,
  158. byte[] keyBytes,
  159. int offset,
  160. int length)
  161. {
  162. return CreateKeyParameter(algOid.Id, keyBytes, offset, length);
  163. }
  164. public static KeyParameter CreateKeyParameter(
  165. string algorithm,
  166. byte[] keyBytes,
  167. int offset,
  168. int length)
  169. {
  170. if (algorithm == null)
  171. throw new ArgumentNullException("algorithm");
  172. string canonical = GetCanonicalAlgorithmName(algorithm);
  173. if (canonical == null)
  174. throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
  175. if (canonical == "DES")
  176. return new DesParameters(keyBytes, offset, length);
  177. if (canonical == "DESEDE" || canonical =="DESEDE3")
  178. return new DesEdeParameters(keyBytes, offset, length);
  179. if (canonical == "RC2")
  180. return new RC2Parameters(keyBytes, offset, length);
  181. return new KeyParameter(keyBytes, offset, length);
  182. }
  183. public static ICipherParameters GetCipherParameters(
  184. DerObjectIdentifier algOid,
  185. ICipherParameters key,
  186. Asn1Object asn1Params)
  187. {
  188. return GetCipherParameters(algOid.Id, key, asn1Params);
  189. }
  190. public static ICipherParameters GetCipherParameters(
  191. string algorithm,
  192. ICipherParameters key,
  193. Asn1Object asn1Params)
  194. {
  195. if (algorithm == null)
  196. throw new ArgumentNullException("algorithm");
  197. string canonical = GetCanonicalAlgorithmName(algorithm);
  198. if (canonical == null)
  199. throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
  200. byte[] iv = null;
  201. try
  202. {
  203. // TODO These algorithms support an IV
  204. // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them
  205. // "RIJNDAEL", "SKIPJACK", "TWOFISH"
  206. int basicIVKeySize = FindBasicIVSize(canonical);
  207. if (basicIVKeySize != -1
  208. || canonical == "RIJNDAEL" || canonical == "SKIPJACK" || canonical == "TWOFISH")
  209. {
  210. iv = ((Asn1OctetString) asn1Params).GetOctets();
  211. }
  212. else if (canonical == "CAST5")
  213. {
  214. iv = Cast5CbcParameters.GetInstance(asn1Params).GetIV();
  215. }
  216. else if (canonical == "IDEA")
  217. {
  218. iv = IdeaCbcPar.GetInstance(asn1Params).GetIV();
  219. }
  220. else if (canonical == "RC2")
  221. {
  222. iv = RC2CbcParameter.GetInstance(asn1Params).GetIV();
  223. }
  224. }
  225. catch (Exception e)
  226. {
  227. throw new ArgumentException("Could not process ASN.1 parameters", e);
  228. }
  229. if (iv != null)
  230. {
  231. return new ParametersWithIV(key, iv);
  232. }
  233. throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
  234. }
  235. public static Asn1Encodable GenerateParameters(
  236. DerObjectIdentifier algID,
  237. SecureRandom random)
  238. {
  239. return GenerateParameters(algID.Id, random);
  240. }
  241. public static Asn1Encodable GenerateParameters(
  242. string algorithm,
  243. SecureRandom random)
  244. {
  245. if (algorithm == null)
  246. throw new ArgumentNullException("algorithm");
  247. string canonical = GetCanonicalAlgorithmName(algorithm);
  248. if (canonical == null)
  249. throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
  250. // TODO These algorithms support an IV
  251. // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them
  252. // "RIJNDAEL", "SKIPJACK", "TWOFISH"
  253. int basicIVKeySize = FindBasicIVSize(canonical);
  254. if (basicIVKeySize != -1)
  255. return CreateIVOctetString(random, basicIVKeySize);
  256. if (canonical == "CAST5")
  257. return new Cast5CbcParameters(CreateIV(random, 8), 128);
  258. if (canonical == "IDEA")
  259. return new IdeaCbcPar(CreateIV(random, 8));
  260. if (canonical == "RC2")
  261. return new RC2CbcParameter(CreateIV(random, 8));
  262. throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
  263. }
  264. public static ICipherParameters WithRandom(ICipherParameters cp, SecureRandom random)
  265. {
  266. if (random != null)
  267. {
  268. cp = new ParametersWithRandom(cp, random);
  269. }
  270. return cp;
  271. }
  272. private static Asn1OctetString CreateIVOctetString(
  273. SecureRandom random,
  274. int ivLength)
  275. {
  276. return new DerOctetString(CreateIV(random, ivLength));
  277. }
  278. private static byte[] CreateIV(
  279. SecureRandom random,
  280. int ivLength)
  281. {
  282. byte[] iv = new byte[ivLength];
  283. random.NextBytes(iv);
  284. return iv;
  285. }
  286. private static int FindBasicIVSize(
  287. string canonicalName)
  288. {
  289. if (!basicIVSizes.Contains(canonicalName))
  290. return -1;
  291. return (int)basicIVSizes[canonicalName];
  292. }
  293. }
  294. }
  295. #pragma warning restore
  296. #endif