TlsClientHello.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Transport Security Layer (TLS)
  2. // Copyright (c) 2003-2004 Carlos Guzman Alvarez
  3. // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining
  6. // a copy of this software and associated documentation files (the
  7. // "Software"), to deal in the Software without restriction, including
  8. // without limitation the rights to use, copy, modify, merge, publish,
  9. // distribute, sublicense, and/or sell copies of the Software, and to
  10. // permit persons to whom the Software is furnished to do so, subject to
  11. // the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  20. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  21. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. //
  24. using System;
  25. using System.Security.Cryptography;
  26. namespace Mono.Security.Protocol.Tls.Handshake.Server
  27. {
  28. internal class TlsClientHello : HandshakeMessage
  29. {
  30. #region Private Fields
  31. private byte[] random;
  32. private byte[] sessionId;
  33. private short[] cipherSuites;
  34. private byte[] compressionMethods;
  35. #endregion
  36. #region Constructors
  37. public TlsClientHello(Context context, byte[] buffer)
  38. : base(context, HandshakeType.ClientHello, buffer)
  39. {
  40. }
  41. #endregion
  42. #region Methods
  43. public override void Update()
  44. {
  45. base.Update();
  46. this.selectCipherSuite();
  47. this.selectCompressionMethod();
  48. this.Context.SessionId = this.sessionId;
  49. this.Context.ClientRandom = this.random;
  50. this.Context.ProtocolNegotiated = true;
  51. }
  52. #endregion
  53. #region Protected Methods
  54. protected override void ProcessAsSsl3()
  55. {
  56. this.ProcessAsTls1();
  57. }
  58. protected override void ProcessAsTls1()
  59. {
  60. // Client Version
  61. this.processProtocol(this.ReadInt16());
  62. // Random bytes - Unix time + Radom bytes [28]
  63. this.random = this.ReadBytes(32);
  64. // Session id
  65. // Send the session ID empty
  66. this.sessionId = this.ReadBytes(this.ReadByte());
  67. // Read Supported Cipher Suites count
  68. this.cipherSuites = new short[this.ReadInt16()/2];
  69. // Read Cipher Suites
  70. for (int i = 0; i < this.cipherSuites.Length; i++)
  71. {
  72. this.cipherSuites[i] = this.ReadInt16();
  73. }
  74. // Compression methods length
  75. this.compressionMethods = new byte[this.ReadByte()];
  76. for (int i = 0; i < this.compressionMethods.Length; i++)
  77. {
  78. this.compressionMethods[i] = this.ReadByte();
  79. }
  80. }
  81. #endregion
  82. #region Private Methods
  83. private void processProtocol(short protocol)
  84. {
  85. SecurityProtocolType clientProtocol = this.Context.DecodeProtocolCode(protocol);
  86. if ((clientProtocol & this.Context.SecurityProtocolFlags) == clientProtocol ||
  87. (this.Context.SecurityProtocolFlags & SecurityProtocolType.Default) == SecurityProtocolType.Default)
  88. {
  89. this.Context.SecurityProtocol = clientProtocol;
  90. this.Context.SupportedCiphers.Clear();
  91. this.Context.SupportedCiphers = null;
  92. this.Context.SupportedCiphers = CipherSuiteFactory.GetSupportedCiphers(clientProtocol);
  93. }
  94. else
  95. {
  96. throw new TlsException(AlertDescription.ProtocolVersion, "Incorrect protocol version received from server");
  97. }
  98. }
  99. private void selectCipherSuite()
  100. {
  101. int index = 0;
  102. for (int i = 0; i < this.cipherSuites.Length; i++)
  103. {
  104. if ((index = this.Context.SupportedCiphers.IndexOf(this.cipherSuites[i])) != -1)
  105. {
  106. this.Context.Negotiating.Cipher = this.Context.SupportedCiphers[index];
  107. break;
  108. }
  109. }
  110. if (this.Context.Negotiating.Cipher == null)
  111. {
  112. throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security");
  113. }
  114. }
  115. private void selectCompressionMethod()
  116. {
  117. this.Context.CompressionMethod = SecurityCompressionType.None;
  118. }
  119. #endregion
  120. }
  121. }