NTLMv2ClientChallenge.cs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* Copyright (C) 2014 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.Text;
  10. using Utilities;
  11. namespace SMBLibrary.Authentication
  12. {
  13. /// <summary>
  14. /// NTLMv2_CLIENT_CHALLENGE
  15. /// </summary>
  16. public class NTLMv2ClientChallengeStructure
  17. {
  18. public static readonly DateTime EpochTime = DateTime.FromFileTimeUtc(0);
  19. public byte ResponseVersion;
  20. public byte ResponseVersionHigh;
  21. public DateTime Time;
  22. public byte[] ClientChallenge;
  23. public KeyValuePairList<AVPairKey, byte[]> AVPairs;
  24. public NTLMv2ClientChallengeStructure()
  25. {
  26. }
  27. public NTLMv2ClientChallengeStructure(DateTime time, byte[] clientChallenge, string domainName, string computerName)
  28. {
  29. ResponseVersion = 1;
  30. ResponseVersionHigh = 1;
  31. Time = time;
  32. ClientChallenge = clientChallenge;
  33. AVPairs = new KeyValuePairList<AVPairKey, byte[]>();
  34. AVPairs.Add(AVPairKey.NbDomainName, UnicodeEncoding.Unicode.GetBytes(domainName));
  35. AVPairs.Add(AVPairKey.NbComputerName, UnicodeEncoding.Unicode.GetBytes(computerName));
  36. }
  37. public NTLMv2ClientChallengeStructure(byte[] buffer) : this(buffer, 0)
  38. {
  39. }
  40. public NTLMv2ClientChallengeStructure(byte[] buffer, int offset)
  41. {
  42. ResponseVersion = ByteReader.ReadByte(buffer, offset + 0);
  43. ResponseVersionHigh = ByteReader.ReadByte(buffer, offset + 1);
  44. long temp = LittleEndianConverter.ToInt64(buffer, offset + 8);
  45. Time = DateTime.FromFileTimeUtc(temp);
  46. ClientChallenge = ByteReader.ReadBytes(buffer, offset + 16, 8);
  47. AVPairs = AVPairUtils.ReadAVPairSequence(buffer, offset + 28);
  48. }
  49. public byte[] GetBytes()
  50. {
  51. byte[] sequenceBytes = AVPairUtils.GetAVPairSequenceBytes(AVPairs);
  52. byte[] timeBytes = LittleEndianConverter.GetBytes((ulong)Time.ToFileTimeUtc());
  53. byte[] buffer = new byte[28 + sequenceBytes.Length];
  54. ByteWriter.WriteByte(buffer, 0, ResponseVersion);
  55. ByteWriter.WriteByte(buffer, 1, ResponseVersionHigh);
  56. ByteWriter.WriteBytes(buffer, 8, timeBytes);
  57. ByteWriter.WriteBytes(buffer, 16, ClientChallenge, 8);
  58. ByteWriter.WriteBytes(buffer, 28, sequenceBytes);
  59. return buffer;
  60. }
  61. /// <summary>
  62. /// [MS-NLMP] Page 60, Response key calculation algorithm:
  63. /// To create 'temp', 4 zero bytes will be appended to NTLMv2_CLIENT_CHALLENGE
  64. /// </summary>
  65. public byte[] GetBytesPadded()
  66. {
  67. return ByteUtils.Concatenate(GetBytes(), new byte[4]);
  68. }
  69. }
  70. }