ParameterUtilities.cs 14 KB

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