SimpleProtectedNegotiationTokenResponse.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using Utilities;
  11. namespace SMBLibrary.Authentication
  12. {
  13. public enum NegState : byte
  14. {
  15. AcceptCompleted = 0x00,
  16. AcceptIncomplete = 0x01,
  17. Reject = 0x02,
  18. RequestMic = 0x03,
  19. }
  20. /// <summary>
  21. /// RFC 4178 - negTokenResp
  22. /// </summary>
  23. public class SimpleProtectedNegotiationTokenResponse : SimpleProtectedNegotiationToken
  24. {
  25. public const byte NegTokenRespTag = 0xA1;
  26. public const byte NegStateTag = 0xA0;
  27. public const byte SupportedMechanismTag = 0xA1;
  28. public const byte ResponseTokenTag = 0xA2;
  29. public const byte MechanismListMICTag = 0xA3;
  30. public NegState? NegState; // Optional
  31. public byte[] SupportedMechanism; // Optional
  32. public byte[] ResponseToken; // Optional
  33. public byte[] MechanismListMIC; // Optional
  34. public SimpleProtectedNegotiationTokenResponse()
  35. {
  36. }
  37. /// <param name="offset">The offset following the NegTokenResp tag</param>
  38. public SimpleProtectedNegotiationTokenResponse(byte[] buffer, int offset)
  39. {
  40. int constuctionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  41. byte tag = ByteReader.ReadByte(buffer, ref offset);
  42. if (tag != (byte)DerEncodingTag.Sequence)
  43. {
  44. throw new InvalidDataException();
  45. }
  46. int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  47. int sequenceEndOffset = offset + sequenceLength;
  48. while (offset < sequenceEndOffset)
  49. {
  50. tag = ByteReader.ReadByte(buffer, ref offset);
  51. if (tag == NegStateTag)
  52. {
  53. NegState = ReadNegState(buffer, ref offset);
  54. }
  55. else if (tag == SupportedMechanismTag)
  56. {
  57. SupportedMechanism = ReadSupportedMechanism(buffer, ref offset);
  58. }
  59. else if (tag == ResponseTokenTag)
  60. {
  61. ResponseToken = ReadResponseToken(buffer, ref offset);
  62. }
  63. else if (tag == MechanismListMICTag)
  64. {
  65. MechanismListMIC = ReadMechanismListMIC(buffer, ref offset);
  66. }
  67. else
  68. {
  69. throw new InvalidDataException("Invalid negTokenResp structure");
  70. }
  71. }
  72. }
  73. public override byte[] GetBytes()
  74. {
  75. int sequenceLength = GetTokenFieldsLength();
  76. int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength);
  77. int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength;
  78. int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(constructionLength);
  79. int bufferSize = 1 + constructionLengthFieldSize + 1 + sequenceLengthFieldSize + sequenceLength;
  80. byte[] buffer = new byte[bufferSize];
  81. int offset = 0;
  82. ByteWriter.WriteByte(buffer, ref offset, NegTokenRespTag);
  83. DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength);
  84. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence);
  85. DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength);
  86. if (NegState.HasValue)
  87. {
  88. WriteNegState(buffer, ref offset, NegState.Value);
  89. }
  90. if (SupportedMechanism != null)
  91. {
  92. WriteSupportedMechanism(buffer, ref offset, SupportedMechanism);
  93. }
  94. if (ResponseToken != null)
  95. {
  96. WriteResponseToken(buffer, ref offset, ResponseToken);
  97. }
  98. if (MechanismListMIC != null)
  99. {
  100. WriteMechanismListMIC(buffer, ref offset, MechanismListMIC);
  101. }
  102. return buffer;
  103. }
  104. private int GetTokenFieldsLength()
  105. {
  106. int result = 0;
  107. if (NegState.HasValue)
  108. {
  109. int negStateLength = 5;
  110. result += negStateLength;
  111. }
  112. if (SupportedMechanism != null)
  113. {
  114. int supportedMechanismBytesLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(SupportedMechanism.Length);
  115. int supportedMechanismConstructionLength = 1 + supportedMechanismBytesLengthFieldSize + SupportedMechanism.Length;
  116. int supportedMechanismConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(supportedMechanismConstructionLength);
  117. int supportedMechanismLength = 1 + supportedMechanismConstructionLengthFieldSize + 1 + supportedMechanismBytesLengthFieldSize + SupportedMechanism.Length;
  118. result += supportedMechanismLength;
  119. }
  120. if (ResponseToken != null)
  121. {
  122. int responseTokenBytesLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(ResponseToken.Length);
  123. int responseTokenConstructionLength = 1 + responseTokenBytesLengthFieldSize + ResponseToken.Length;
  124. int responseTokenConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(responseTokenConstructionLength);
  125. int responseTokenLength = 1 + responseTokenConstructionLengthFieldSize + 1 + responseTokenBytesLengthFieldSize + ResponseToken.Length;
  126. result += responseTokenLength;
  127. }
  128. return result;
  129. }
  130. private static NegState ReadNegState(byte[] buffer, ref int offset)
  131. {
  132. int length = DerEncodingHelper.ReadLength(buffer, ref offset);
  133. byte tag = ByteReader.ReadByte(buffer, ref offset);
  134. if (tag != (byte)DerEncodingTag.Enum)
  135. {
  136. throw new InvalidDataException();
  137. }
  138. length = DerEncodingHelper.ReadLength(buffer, ref offset);
  139. return (NegState)ByteReader.ReadByte(buffer, ref offset);
  140. }
  141. private static byte[] ReadSupportedMechanism(byte[] buffer, ref int offset)
  142. {
  143. int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  144. byte tag = ByteReader.ReadByte(buffer, ref offset);
  145. if (tag != (byte)DerEncodingTag.ObjectIdentifier)
  146. {
  147. throw new InvalidDataException();
  148. }
  149. int length = DerEncodingHelper.ReadLength(buffer, ref offset);
  150. return ByteReader.ReadBytes(buffer, ref offset, length);
  151. }
  152. private static byte[] ReadResponseToken(byte[] buffer, ref int offset)
  153. {
  154. int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  155. byte tag = ByteReader.ReadByte(buffer, ref offset);
  156. if (tag != (byte)DerEncodingTag.ByteArray)
  157. {
  158. throw new InvalidDataException();
  159. }
  160. int length = DerEncodingHelper.ReadLength(buffer, ref offset);
  161. return ByteReader.ReadBytes(buffer, ref offset, length);
  162. }
  163. private static byte[] ReadMechanismListMIC(byte[] buffer, ref int offset)
  164. {
  165. int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  166. byte tag = ByteReader.ReadByte(buffer, ref offset);
  167. if (tag != (byte)DerEncodingTag.ByteArray)
  168. {
  169. throw new InvalidDataException();
  170. }
  171. int length = DerEncodingHelper.ReadLength(buffer, ref offset);
  172. return ByteReader.ReadBytes(buffer, ref offset, length);
  173. }
  174. private static void WriteNegState(byte[] buffer, ref int offset, NegState negState)
  175. {
  176. ByteWriter.WriteByte(buffer, ref offset, NegStateTag);
  177. DerEncodingHelper.WriteLength(buffer, ref offset, 3);
  178. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Enum);
  179. DerEncodingHelper.WriteLength(buffer, ref offset, 1);
  180. ByteWriter.WriteByte(buffer, ref offset, (byte)negState);
  181. }
  182. private static void WriteSupportedMechanism(byte[] buffer, ref int offset, byte[] supportedMechanism)
  183. {
  184. int supportedMechanismLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(supportedMechanism.Length);
  185. ByteWriter.WriteByte(buffer, ref offset, SupportedMechanismTag);
  186. DerEncodingHelper.WriteLength(buffer, ref offset, 1 + supportedMechanismLengthFieldSize + supportedMechanism.Length);
  187. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier);
  188. DerEncodingHelper.WriteLength(buffer, ref offset, supportedMechanism.Length);
  189. ByteWriter.WriteBytes(buffer, ref offset, supportedMechanism);
  190. }
  191. private static void WriteResponseToken(byte[] buffer, ref int offset, byte[] responseToken)
  192. {
  193. int responseTokenLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(responseToken.Length);
  194. ByteWriter.WriteByte(buffer, ref offset, ResponseTokenTag);
  195. DerEncodingHelper.WriteLength(buffer, ref offset, 1 + responseTokenLengthFieldSize + responseToken.Length);
  196. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray);
  197. DerEncodingHelper.WriteLength(buffer, ref offset, responseToken.Length);
  198. ByteWriter.WriteBytes(buffer, ref offset, responseToken);
  199. }
  200. private static void WriteMechanismListMIC(byte[] buffer, ref int offset, byte[] mechanismListMIC)
  201. {
  202. int mechanismListMICLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismListMIC.Length);
  203. ByteWriter.WriteByte(buffer, ref offset, MechanismListMICTag);
  204. DerEncodingHelper.WriteLength(buffer, ref offset, 1 + mechanismListMICLengthFieldSize + mechanismListMIC.Length);
  205. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray);
  206. DerEncodingHelper.WriteLength(buffer, ref offset, mechanismListMIC.Length);
  207. ByteWriter.WriteBytes(buffer, ref offset, mechanismListMIC);
  208. }
  209. }
  210. }