SimpleProtectedNegotiationTokenInit.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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.GSSAPI
  12. {
  13. /// <summary>
  14. /// RFC 4178 - negTokenInit
  15. /// </summary>
  16. public class SimpleProtectedNegotiationTokenInit : SimpleProtectedNegotiationToken
  17. {
  18. public const byte NegTokenInitTag = 0xA0;
  19. public const byte MechanismTypeListTag = 0xA0;
  20. public const byte RequiredFlagsTag = 0xA1;
  21. public const byte MechanismTokenTag = 0xA2;
  22. public const byte MechanismListMICTag = 0xA3;
  23. public List<byte[]> MechanismTypeList; // Optional
  24. // reqFlags - Optional, RECOMMENDED to be left out
  25. public byte[] MechanismToken; // Optional
  26. public byte[] MechanismListMIC; // Optional
  27. public SimpleProtectedNegotiationTokenInit()
  28. {
  29. }
  30. /// <param name="offset">The offset following the NegTokenInit tag</param>
  31. public SimpleProtectedNegotiationTokenInit(byte[] buffer, int offset)
  32. {
  33. int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  34. byte tag = ByteReader.ReadByte(buffer, ref offset);
  35. if (tag != (byte)DerEncodingTag.Sequence)
  36. {
  37. throw new InvalidDataException();
  38. }
  39. int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  40. int sequenceEndOffset = offset + sequenceLength;
  41. while (offset < sequenceEndOffset)
  42. {
  43. tag = ByteReader.ReadByte(buffer, ref offset);
  44. if (tag == MechanismTypeListTag)
  45. {
  46. MechanismTypeList = ReadMechanismTypeList(buffer, ref offset);
  47. }
  48. else if (tag == RequiredFlagsTag)
  49. {
  50. throw new NotImplementedException("negTokenInit.ReqFlags is not implemented");
  51. }
  52. else if (tag == MechanismTokenTag)
  53. {
  54. MechanismToken = ReadMechanismToken(buffer, ref offset);
  55. }
  56. else if (tag == MechanismListMICTag)
  57. {
  58. MechanismListMIC = ReadMechanismListMIC(buffer, ref offset);
  59. }
  60. else
  61. {
  62. throw new InvalidDataException("Invalid negTokenInit structure");
  63. }
  64. }
  65. }
  66. public override byte[] GetBytes()
  67. {
  68. int sequenceLength = GetTokenFieldsLength();
  69. int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength);
  70. int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength;
  71. int constructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(constructionLength);
  72. int bufferSize = 1 + constructionLengthFieldSize + 1 + sequenceLengthFieldSize + sequenceLength;
  73. byte[] buffer = new byte[bufferSize];
  74. int offset = 0;
  75. ByteWriter.WriteByte(buffer, ref offset, NegTokenInitTag);
  76. DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength);
  77. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence);
  78. DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength);
  79. if (MechanismTypeList != null)
  80. {
  81. WriteMechanismTypeList(buffer, ref offset, MechanismTypeList);
  82. }
  83. if (MechanismToken != null)
  84. {
  85. WriteMechanismToken(buffer, ref offset, MechanismToken);
  86. }
  87. if (MechanismListMIC != null)
  88. {
  89. WriteMechanismListMIC(buffer, ref offset, MechanismListMIC);
  90. }
  91. return buffer;
  92. }
  93. private int GetTokenFieldsLength()
  94. {
  95. int result = 0;
  96. if (MechanismTypeList != null)
  97. {
  98. int typeListSequenceLength = GetSequenceLength(MechanismTypeList);
  99. int typeListSequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(typeListSequenceLength);
  100. int typeListConstructionLength = 1 + typeListSequenceLengthFieldSize + typeListSequenceLength;
  101. int typeListConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(typeListConstructionLength);
  102. int typeListLength = 1 + typeListConstructionLengthFieldSize + 1 + typeListSequenceLengthFieldSize + typeListSequenceLength;
  103. result += typeListLength;
  104. }
  105. if (MechanismToken != null)
  106. {
  107. int mechanismTokenBytesFieldSize = DerEncodingHelper.GetLengthFieldSize(MechanismToken.Length);
  108. int mechanismTokenConstructionLength = 1 + mechanismTokenBytesFieldSize + MechanismToken.Length;
  109. int mechanismTokenConstructionLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismTokenConstructionLength);
  110. int tokenLength = 1 + mechanismTokenConstructionLengthFieldSize + 1 + mechanismTokenBytesFieldSize + MechanismToken.Length;
  111. result += tokenLength;
  112. }
  113. return result;
  114. }
  115. private static List<byte[]> ReadMechanismTypeList(byte[] buffer, ref int offset)
  116. {
  117. List<byte[]> result = new List<byte[]>();
  118. int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  119. byte tag = ByteReader.ReadByte(buffer, ref offset);
  120. if (tag != (byte)DerEncodingTag.Sequence)
  121. {
  122. throw new InvalidDataException();
  123. }
  124. int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  125. int sequenceEndOffset = offset + sequenceLength;
  126. while (offset < sequenceEndOffset)
  127. {
  128. tag = ByteReader.ReadByte(buffer, ref offset);
  129. if (tag != (byte)DerEncodingTag.ObjectIdentifier)
  130. {
  131. throw new InvalidDataException();
  132. }
  133. int mechanismTypeLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  134. byte[] mechanismType = ByteReader.ReadBytes(buffer, ref offset, mechanismTypeLength);
  135. result.Add(mechanismType);
  136. }
  137. return result;
  138. }
  139. private static byte[] ReadMechanismToken(byte[] buffer, ref int offset)
  140. {
  141. int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  142. byte tag = ByteReader.ReadByte(buffer, ref offset);
  143. if (tag != (byte)DerEncodingTag.ByteArray)
  144. {
  145. throw new InvalidDataException();
  146. }
  147. int mechanismTokenLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  148. byte[] token = ByteReader.ReadBytes(buffer, ref offset, mechanismTokenLength);
  149. return token;
  150. }
  151. private static byte[] ReadMechanismListMIC(byte[] buffer, ref int offset)
  152. {
  153. int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset);
  154. byte tag = ByteReader.ReadByte(buffer, ref offset);
  155. if (tag != (byte)DerEncodingTag.ByteArray)
  156. {
  157. throw new InvalidDataException();
  158. }
  159. int length = DerEncodingHelper.ReadLength(buffer, ref offset);
  160. return ByteReader.ReadBytes(buffer, ref offset, length);
  161. }
  162. private static int GetSequenceLength(List<byte[]> mechanismTypeList)
  163. {
  164. int sequenceLength = 0;
  165. foreach (byte[] mechanismType in mechanismTypeList)
  166. {
  167. int lengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismType.Length);
  168. int entryLength = 1 + lengthFieldSize + mechanismType.Length;
  169. sequenceLength += entryLength;
  170. }
  171. return sequenceLength;
  172. }
  173. private static void WriteMechanismTypeList(byte[] buffer, ref int offset, List<byte[]> mechanismTypeList)
  174. {
  175. int sequenceLength = GetSequenceLength(mechanismTypeList);
  176. int sequenceLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(sequenceLength);
  177. int constructionLength = 1 + sequenceLengthFieldSize + sequenceLength;
  178. ByteWriter.WriteByte(buffer, ref offset, MechanismTypeListTag);
  179. DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength);
  180. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.Sequence);
  181. DerEncodingHelper.WriteLength(buffer, ref offset, sequenceLength);
  182. foreach (byte[] mechanismType in mechanismTypeList)
  183. {
  184. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier);
  185. DerEncodingHelper.WriteLength(buffer, ref offset, mechanismType.Length);
  186. ByteWriter.WriteBytes(buffer, ref offset, mechanismType);
  187. }
  188. }
  189. private static void WriteMechanismToken(byte[] buffer, ref int offset, byte[] mechanismToken)
  190. {
  191. int constructionLength = 1 + DerEncodingHelper.GetLengthFieldSize(mechanismToken.Length) + mechanismToken.Length;
  192. ByteWriter.WriteByte(buffer, ref offset, MechanismTokenTag);
  193. DerEncodingHelper.WriteLength(buffer, ref offset, constructionLength);
  194. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray);
  195. DerEncodingHelper.WriteLength(buffer, ref offset, mechanismToken.Length);
  196. ByteWriter.WriteBytes(buffer, ref offset, mechanismToken);
  197. }
  198. private static void WriteMechanismListMIC(byte[] buffer, ref int offset, byte[] mechanismListMIC)
  199. {
  200. int mechanismListMICLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(mechanismListMIC.Length);
  201. ByteWriter.WriteByte(buffer, ref offset, MechanismListMICTag);
  202. DerEncodingHelper.WriteLength(buffer, ref offset, 1 + mechanismListMICLengthFieldSize + mechanismListMIC.Length);
  203. ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ByteArray);
  204. DerEncodingHelper.WriteLength(buffer, ref offset, mechanismListMIC.Length);
  205. ByteWriter.WriteBytes(buffer, ref offset, mechanismListMIC);
  206. }
  207. }
  208. }