ServerNameList.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
  9. {
  10. public sealed class ServerNameList
  11. {
  12. private readonly IList m_serverNameList;
  13. /// <param name="serverNameList">an <see cref="IList"/> of <see cref="ServerName"/>.</param>
  14. public ServerNameList(IList serverNameList)
  15. {
  16. if (null == serverNameList)
  17. throw new ArgumentNullException("serverNameList");
  18. this.m_serverNameList = serverNameList;
  19. }
  20. /// <returns>an <see cref="IList"/> of <see cref="ServerName"/>.</returns>
  21. public IList ServerNames
  22. {
  23. get { return m_serverNameList; }
  24. }
  25. /// <summary>Encode this <see cref="ServerNameList"/> to a <see cref="Stream"/>.</summary>
  26. /// <param name="output">the <see cref="Stream"/> to encode to .</param>
  27. /// <exception cref="IOException"/>
  28. public void Encode(Stream output)
  29. {
  30. MemoryStream buf = new MemoryStream();
  31. short[] nameTypesSeen = TlsUtilities.EmptyShorts;
  32. foreach (ServerName entry in ServerNames)
  33. {
  34. nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType);
  35. if (null == nameTypesSeen)
  36. throw new TlsFatalAlert(AlertDescription.internal_error);
  37. entry.Encode(buf);
  38. }
  39. int length = (int)buf.Length;
  40. TlsUtilities.CheckUint16(length);
  41. TlsUtilities.WriteUint16(length, output);
  42. Streams.WriteBufTo(buf, output);
  43. }
  44. /// <summary>Parse a <see cref="ServerNameList"/> from a <see cref="Stream"/>.</summary>
  45. /// <param name="input">the <see cref="Stream"/> to parse from.</param>
  46. /// <returns>a <see cref="ServerNameList"/> object.</returns>
  47. /// <exception cref="IOException"/>
  48. public static ServerNameList Parse(Stream input)
  49. {
  50. byte[] data = TlsUtilities.ReadOpaque16(input, 1);
  51. MemoryStream buf = new MemoryStream(data, false);
  52. short[] nameTypesSeen = TlsUtilities.EmptyShorts;
  53. IList server_name_list = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
  54. while (buf.Position < buf.Length)
  55. {
  56. ServerName entry = ServerName.Parse(buf);
  57. nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType);
  58. if (null == nameTypesSeen)
  59. throw new TlsFatalAlert(AlertDescription.illegal_parameter);
  60. server_name_list.Add(entry);
  61. }
  62. return new ServerNameList(server_name_list);
  63. }
  64. private static short[] CheckNameType(short[] nameTypesSeen, short nameType)
  65. {
  66. // RFC 6066 3. The ServerNameList MUST NOT contain more than one name of the same NameType.
  67. if (Arrays.Contains(nameTypesSeen, nameType))
  68. return null;
  69. return Arrays.Append(nameTypesSeen, nameType);
  70. }
  71. }
  72. }
  73. #pragma warning restore
  74. #endif