TlsExtensionsUtilities.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using System.IO;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
  8. {
  9. public abstract class TlsExtensionsUtilities
  10. {
  11. public static IDictionary EnsureExtensionsInitialised(IDictionary extensions)
  12. {
  13. return extensions == null ? BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable() : extensions;
  14. }
  15. /// <exception cref="IOException"></exception>
  16. public static void AddClientCertificateTypeExtensionClient(IDictionary extensions, byte[] certificateTypes)
  17. {
  18. extensions[ExtensionType.client_certificate_type] = CreateCertificateTypeExtensionClient(certificateTypes);
  19. }
  20. /// <exception cref="IOException"></exception>
  21. public static void AddClientCertificateTypeExtensionServer(IDictionary extensions, byte certificateType)
  22. {
  23. extensions[ExtensionType.client_certificate_type] = CreateCertificateTypeExtensionServer(certificateType);
  24. }
  25. public static void AddEncryptThenMacExtension(IDictionary extensions)
  26. {
  27. extensions[ExtensionType.encrypt_then_mac] = CreateEncryptThenMacExtension();
  28. }
  29. public static void AddExtendedMasterSecretExtension(IDictionary extensions)
  30. {
  31. extensions[ExtensionType.extended_master_secret] = CreateExtendedMasterSecretExtension();
  32. }
  33. /// <exception cref="IOException"></exception>
  34. public static void AddHeartbeatExtension(IDictionary extensions, HeartbeatExtension heartbeatExtension)
  35. {
  36. extensions[ExtensionType.heartbeat] = CreateHeartbeatExtension(heartbeatExtension);
  37. }
  38. /// <exception cref="IOException"></exception>
  39. public static void AddMaxFragmentLengthExtension(IDictionary extensions, byte maxFragmentLength)
  40. {
  41. extensions[ExtensionType.max_fragment_length] = CreateMaxFragmentLengthExtension(maxFragmentLength);
  42. }
  43. /// <exception cref="IOException"></exception>
  44. public static void AddPaddingExtension(IDictionary extensions, int dataLength)
  45. {
  46. extensions[ExtensionType.padding] = CreatePaddingExtension(dataLength);
  47. }
  48. /// <exception cref="IOException"></exception>
  49. public static void AddServerCertificateTypeExtensionClient(IDictionary extensions, byte[] certificateTypes)
  50. {
  51. extensions[ExtensionType.server_certificate_type] = CreateCertificateTypeExtensionClient(certificateTypes);
  52. }
  53. /// <exception cref="IOException"></exception>
  54. public static void AddServerCertificateTypeExtensionServer(IDictionary extensions, byte certificateType)
  55. {
  56. extensions[ExtensionType.server_certificate_type] = CreateCertificateTypeExtensionServer(certificateType);
  57. }
  58. /// <exception cref="IOException"></exception>
  59. public static void AddServerNameExtension(IDictionary extensions, ServerNameList serverNameList)
  60. {
  61. extensions[ExtensionType.server_name] = CreateServerNameExtension(serverNameList);
  62. }
  63. /// <exception cref="IOException"></exception>
  64. public static void AddStatusRequestExtension(IDictionary extensions, CertificateStatusRequest statusRequest)
  65. {
  66. extensions[ExtensionType.status_request] = CreateStatusRequestExtension(statusRequest);
  67. }
  68. public static void AddTruncatedHMacExtension(IDictionary extensions)
  69. {
  70. extensions[ExtensionType.truncated_hmac] = CreateTruncatedHMacExtension();
  71. }
  72. /// <exception cref="IOException"></exception>
  73. public static byte[] GetClientCertificateTypeExtensionClient(IDictionary extensions)
  74. {
  75. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_type);
  76. return extensionData == null ? null : ReadCertificateTypeExtensionClient(extensionData);
  77. }
  78. /// <exception cref="IOException"></exception>
  79. public static short GetClientCertificateTypeExtensionServer(IDictionary extensions)
  80. {
  81. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_type);
  82. return extensionData == null ? (short)-1 : (short)ReadCertificateTypeExtensionServer(extensionData);
  83. }
  84. /// <exception cref="IOException"></exception>
  85. public static HeartbeatExtension GetHeartbeatExtension(IDictionary extensions)
  86. {
  87. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.heartbeat);
  88. return extensionData == null ? null : ReadHeartbeatExtension(extensionData);
  89. }
  90. /// <exception cref="IOException"></exception>
  91. public static short GetMaxFragmentLengthExtension(IDictionary extensions)
  92. {
  93. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.max_fragment_length);
  94. return extensionData == null ? (short)-1 : (short)ReadMaxFragmentLengthExtension(extensionData);
  95. }
  96. /// <exception cref="IOException"></exception>
  97. public static int GetPaddingExtension(IDictionary extensions)
  98. {
  99. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.padding);
  100. return extensionData == null ? -1 : ReadPaddingExtension(extensionData);
  101. }
  102. /// <exception cref="IOException"></exception>
  103. public static byte[] GetServerCertificateTypeExtensionClient(IDictionary extensions)
  104. {
  105. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_certificate_type);
  106. return extensionData == null ? null : ReadCertificateTypeExtensionClient(extensionData);
  107. }
  108. /// <exception cref="IOException"></exception>
  109. public static short GetServerCertificateTypeExtensionServer(IDictionary extensions)
  110. {
  111. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_certificate_type);
  112. return extensionData == null ? (short)-1 : (short)ReadCertificateTypeExtensionServer(extensionData);
  113. }
  114. /// <exception cref="IOException"></exception>
  115. public static ServerNameList GetServerNameExtension(IDictionary extensions)
  116. {
  117. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_name);
  118. return extensionData == null ? null : ReadServerNameExtension(extensionData);
  119. }
  120. /// <exception cref="IOException"></exception>
  121. public static CertificateStatusRequest GetStatusRequestExtension(IDictionary extensions)
  122. {
  123. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.status_request);
  124. return extensionData == null ? null : ReadStatusRequestExtension(extensionData);
  125. }
  126. /// <exception cref="IOException"></exception>
  127. public static bool HasEncryptThenMacExtension(IDictionary extensions)
  128. {
  129. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.encrypt_then_mac);
  130. return extensionData == null ? false : ReadEncryptThenMacExtension(extensionData);
  131. }
  132. /// <exception cref="IOException"></exception>
  133. public static bool HasExtendedMasterSecretExtension(IDictionary extensions)
  134. {
  135. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.extended_master_secret);
  136. return extensionData == null ? false : ReadExtendedMasterSecretExtension(extensionData);
  137. }
  138. /// <exception cref="IOException"></exception>
  139. public static bool HasTruncatedHMacExtension(IDictionary extensions)
  140. {
  141. byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.truncated_hmac);
  142. return extensionData == null ? false : ReadTruncatedHMacExtension(extensionData);
  143. }
  144. /// <exception cref="IOException"></exception>
  145. public static byte[] CreateCertificateTypeExtensionClient(byte[] certificateTypes)
  146. {
  147. if (certificateTypes == null || certificateTypes.Length < 1 || certificateTypes.Length > 255)
  148. throw new TlsFatalAlert(AlertDescription.internal_error);
  149. return TlsUtilities.EncodeUint8ArrayWithUint8Length(certificateTypes);
  150. }
  151. /// <exception cref="IOException"></exception>
  152. public static byte[] CreateCertificateTypeExtensionServer(byte certificateType)
  153. {
  154. return TlsUtilities.EncodeUint8(certificateType);
  155. }
  156. public static byte[] CreateEmptyExtensionData()
  157. {
  158. return TlsUtilities.EmptyBytes;
  159. }
  160. public static byte[] CreateEncryptThenMacExtension()
  161. {
  162. return CreateEmptyExtensionData();
  163. }
  164. public static byte[] CreateExtendedMasterSecretExtension()
  165. {
  166. return CreateEmptyExtensionData();
  167. }
  168. /// <exception cref="IOException"></exception>
  169. public static byte[] CreateHeartbeatExtension(HeartbeatExtension heartbeatExtension)
  170. {
  171. if (heartbeatExtension == null)
  172. throw new TlsFatalAlert(AlertDescription.internal_error);
  173. MemoryStream buf = new MemoryStream();
  174. heartbeatExtension.Encode(buf);
  175. return buf.ToArray();
  176. }
  177. /// <exception cref="IOException"></exception>
  178. public static byte[] CreateMaxFragmentLengthExtension(byte maxFragmentLength)
  179. {
  180. return TlsUtilities.EncodeUint8(maxFragmentLength);
  181. }
  182. /// <exception cref="IOException"></exception>
  183. public static byte[] CreatePaddingExtension(int dataLength)
  184. {
  185. TlsUtilities.CheckUint16(dataLength);
  186. return new byte[dataLength];
  187. }
  188. /// <exception cref="IOException"></exception>
  189. public static byte[] CreateServerNameExtension(ServerNameList serverNameList)
  190. {
  191. if (serverNameList == null)
  192. throw new TlsFatalAlert(AlertDescription.internal_error);
  193. MemoryStream buf = new MemoryStream();
  194. serverNameList.Encode(buf);
  195. return buf.ToArray();
  196. }
  197. /// <exception cref="IOException"></exception>
  198. public static byte[] CreateStatusRequestExtension(CertificateStatusRequest statusRequest)
  199. {
  200. if (statusRequest == null)
  201. {
  202. throw new TlsFatalAlert(AlertDescription.internal_error);
  203. }
  204. MemoryStream buf = new MemoryStream();
  205. statusRequest.Encode(buf);
  206. return buf.ToArray();
  207. }
  208. public static byte[] CreateTruncatedHMacExtension()
  209. {
  210. return CreateEmptyExtensionData();
  211. }
  212. /// <exception cref="IOException"></exception>
  213. private static bool ReadEmptyExtensionData(byte[] extensionData)
  214. {
  215. if (extensionData == null)
  216. throw new ArgumentNullException("extensionData");
  217. if (extensionData.Length != 0)
  218. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  219. return true;
  220. }
  221. /// <exception cref="IOException"></exception>
  222. public static byte[] ReadCertificateTypeExtensionClient(byte[] extensionData)
  223. {
  224. byte[] certificateTypes = TlsUtilities.DecodeUint8ArrayWithUint8Length(extensionData);
  225. if (certificateTypes.Length < 1)
  226. throw new TlsFatalAlert(AlertDescription.decode_error);
  227. return certificateTypes;
  228. }
  229. /// <exception cref="IOException"></exception>
  230. public static byte ReadCertificateTypeExtensionServer(byte[] extensionData)
  231. {
  232. return TlsUtilities.DecodeUint8(extensionData);
  233. }
  234. /// <exception cref="IOException"></exception>
  235. public static bool ReadEncryptThenMacExtension(byte[] extensionData)
  236. {
  237. return ReadEmptyExtensionData(extensionData);
  238. }
  239. /// <exception cref="IOException"></exception>
  240. public static bool ReadExtendedMasterSecretExtension(byte[] extensionData)
  241. {
  242. return ReadEmptyExtensionData(extensionData);
  243. }
  244. /// <exception cref="IOException"></exception>
  245. public static HeartbeatExtension ReadHeartbeatExtension(byte[] extensionData)
  246. {
  247. if (extensionData == null)
  248. throw new ArgumentNullException("extensionData");
  249. MemoryStream buf = new MemoryStream(extensionData, false);
  250. HeartbeatExtension heartbeatExtension = HeartbeatExtension.Parse(buf);
  251. TlsProtocol.AssertEmpty(buf);
  252. return heartbeatExtension;
  253. }
  254. /// <exception cref="IOException"></exception>
  255. public static byte ReadMaxFragmentLengthExtension(byte[] extensionData)
  256. {
  257. return TlsUtilities.DecodeUint8(extensionData);
  258. }
  259. /// <exception cref="IOException"></exception>
  260. public static int ReadPaddingExtension(byte[] extensionData)
  261. {
  262. if (extensionData == null)
  263. throw new ArgumentNullException("extensionData");
  264. for (int i = 0; i < extensionData.Length; ++i)
  265. {
  266. if (extensionData[i] != 0)
  267. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  268. }
  269. return extensionData.Length;
  270. }
  271. /// <exception cref="IOException"></exception>
  272. public static ServerNameList ReadServerNameExtension(byte[] extensionData)
  273. {
  274. if (extensionData == null)
  275. throw new ArgumentNullException("extensionData");
  276. MemoryStream buf = new MemoryStream(extensionData, false);
  277. ServerNameList serverNameList = ServerNameList.Parse(buf);
  278. TlsProtocol.AssertEmpty(buf);
  279. return serverNameList;
  280. }
  281. /// <exception cref="IOException"></exception>
  282. public static CertificateStatusRequest ReadStatusRequestExtension(byte[] extensionData)
  283. {
  284. if (extensionData == null)
  285. throw new ArgumentNullException("extensionData");
  286. MemoryStream buf = new MemoryStream(extensionData, false);
  287. CertificateStatusRequest statusRequest = CertificateStatusRequest.Parse(buf);
  288. TlsProtocol.AssertEmpty(buf);
  289. return statusRequest;
  290. }
  291. /// <exception cref="IOException"></exception>
  292. public static bool ReadTruncatedHMacExtension(byte[] extensionData)
  293. {
  294. return ReadEmptyExtensionData(extensionData);
  295. }
  296. }
  297. }
  298. #pragma warning restore
  299. #endif