/// <summary> /// initialize the mic of challenge packet /// </summary> /// <param name="exportedSessionKey">the exported session key</param> /// <param name="targetInfo">the target info contains av pairs.</param> /// <param name="authenticatePacket">the authenticate packet</param> /// <param name="challengePacket">the challenge packet</param> private void InitializeChallengeMIC( byte[] exportedSessionKey, ICollection <AV_PAIR> targetInfo, NlmpAuthenticatePacket authenticatePacket, NlmpChallengePacket challengePacket ) { if (NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsvAvTimestamp)) { // update mic with security algorithm byte[] mic = null; // if connectionless, this.negotiate is null. mic = NlmpUtility.GetMic(exportedSessionKey, this.negotiate, challengePacket, authenticatePacket); // get payload of packet AUTHENTICATE_MESSAGE payload = authenticatePacket.Payload; // update mic to payload payload.MIC = mic; // update the meaningful payload to packet authenticatePacket.Payload = payload; } }
/// <summary> /// copy constructor. /// </summary> /// <param name="stackPacket">the source packet</param> /// <exception cref="ArgumentNullException">the stackPacket.payload.MIC must not be null</exception> /// <exception cref="ArgumentException">the stackPacket.payload.MIC.Length is wrong</exception> public NlmpAuthenticatePacket( NlmpAuthenticatePacket stackPacket ) : base(stackPacket) { this.payload = stackPacket.payload; if (stackPacket.payload.MIC == null) { throw new ArgumentNullException("stackPacket", "the stackPacket.payload.MIC must not be null"); } if (stackPacket.payload.MIC.Length != NlmpUtility.AUTHENTICATE_MESSAGE_MIC_CONST_SIZE) { throw new ArgumentException( string.Format("the stackPacket.payload.MIC.Length must be {0}, actually {1}", NlmpUtility.AUTHENTICATE_MESSAGE_MIC_CONST_SIZE, stackPacket.payload.MIC.Length), "stackPacket"); } this.payload.MIC = new byte[stackPacket.payload.MIC.Length]; Array.Copy(stackPacket.payload.MIC, this.payload.MIC, stackPacket.payload.MIC.Length); if (stackPacket.payload.DomainName != null) { this.payload.DomainName = new byte[stackPacket.payload.DomainName.Length]; Array.Copy( stackPacket.payload.DomainName, this.payload.DomainName, stackPacket.payload.DomainName.Length); } if (stackPacket.payload.UserName != null) { this.payload.UserName = new byte[stackPacket.payload.UserName.Length]; Array.Copy( stackPacket.payload.UserName, this.payload.UserName, stackPacket.payload.UserName.Length); } if (stackPacket.payload.Workstation != null) { this.payload.Workstation = new byte[stackPacket.payload.Workstation.Length]; Array.Copy( stackPacket.payload.Workstation, this.payload.Workstation, stackPacket.payload.Workstation.Length); } if (stackPacket.payload.LmChallengeResponse != null) { this.payload.LmChallengeResponse = new byte[stackPacket.payload.LmChallengeResponse.Length]; Array.Copy( stackPacket.payload.LmChallengeResponse, this.payload.LmChallengeResponse, stackPacket.payload.LmChallengeResponse.Length); } if (stackPacket.payload.NtChallengeResponse != null) { this.payload.NtChallengeResponse = new byte[stackPacket.payload.NtChallengeResponse.Length]; Array.Copy( stackPacket.payload.NtChallengeResponse, this.payload.NtChallengeResponse, stackPacket.payload.NtChallengeResponse.Length); } if (stackPacket.payload.EncryptedRandomSessionKey != null) { this.payload.EncryptedRandomSessionKey = new byte[stackPacket.payload.EncryptedRandomSessionKey.Length]; Array.Copy( stackPacket.payload.EncryptedRandomSessionKey, this.payload.EncryptedRandomSessionKey, stackPacket.payload.EncryptedRandomSessionKey.Length); } }
/// <summary> /// read struct from bytes. All sub class override this to unmarshal itself. /// </summary> /// <param name="start">the start to read bytes</param> /// <param name="packetBytes">the bytes of struct</param> /// <returns>the read result, if success, return true.</returns> protected override bool ReadStructFromBytes( byte[] packetBytes, int start ) { AUTHENTICATE_MESSAGE authenticate = new AUTHENTICATE_MESSAGE(); authenticate.LmChallengeResponseFields = NlmpUtility.BytesToStruct<MESSAGE_FIELDS>( packetBytes, ref start); authenticate.NtChallengeResponseFields = NlmpUtility.BytesToStruct<MESSAGE_FIELDS>( packetBytes, ref start); authenticate.DomainNameFields = NlmpUtility.BytesToStruct<MESSAGE_FIELDS>( packetBytes, ref start); authenticate.UserNameFields = NlmpUtility.BytesToStruct<MESSAGE_FIELDS>( packetBytes, ref start); authenticate.WorkstationFields = NlmpUtility.BytesToStruct<MESSAGE_FIELDS>( packetBytes, ref start); authenticate.EncryptedRandomSessionKeyFields = NlmpUtility.BytesToStruct<MESSAGE_FIELDS>( packetBytes, ref start); authenticate.NegotiateFlags = (NegotiateTypes)NlmpUtility.BytesToStruct<uint>( packetBytes, ref start); authenticate.Version = NlmpUtility.BytesToStruct<VERSION>( packetBytes, ref start); authenticate.MIC = NlmpUtility.ReadBytes( packetBytes, ref start, NlmpUtility.AUTHENTICATE_MESSAGE_MIC_CONST_SIZE); int currentIndex = 0; while (currentIndex != start) { currentIndex = start; if (authenticate.DomainNameFields.Len != 0 && authenticate.DomainNameFields.BufferOffset == start) { authenticate.DomainName = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.DomainNameFields.Len); continue; } else if (authenticate.EncryptedRandomSessionKeyFields.Len != 0 && authenticate.EncryptedRandomSessionKeyFields.BufferOffset == start) { authenticate.EncryptedRandomSessionKey = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.EncryptedRandomSessionKeyFields.Len); continue; } else if (authenticate.LmChallengeResponseFields.Len != 0 && authenticate.LmChallengeResponseFields.BufferOffset == start) { authenticate.LmChallengeResponse = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.LmChallengeResponseFields.Len); continue; } else if (authenticate.NtChallengeResponseFields.Len != 0 && authenticate.NtChallengeResponseFields.BufferOffset == start) { authenticate.NtChallengeResponse = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.NtChallengeResponseFields.Len); continue; } else if (authenticate.UserNameFields.Len != 0 && authenticate.UserNameFields.BufferOffset == start) { authenticate.UserName = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.UserNameFields.Len); continue; } else if (authenticate.WorkstationFields.Len != 0 && authenticate.WorkstationFields.BufferOffset == start) { authenticate.Workstation = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.WorkstationFields.Len); continue; } else { break; } } this.payload = authenticate; return true; }
/// <summary> /// Verify the authenticate packet locally /// </summary> /// <param name="authenticatePacket">actual authenticate packet</param> /// <param name="authenticateInformation">expected authenticate information</param> /// <param name="exportedSessionKey">exported session key</param> /// <returns></returns> private ClientAuthenticateInfomation VerifyAuthenticatePacketLocally( NlmpAuthenticatePacket authenticatePacket, ClientAuthenticateInfomation authenticateInformation, out byte[] exportedSessionKey) { // valid user name if (authenticateInformation.UserName.ToUpper() != this.nlmpServer.Context.ClientCredential.AccountName.ToUpper()) { throw new InvalidOperationException( "the user name is invalid!" + " the user name retrieved form authenticate packet is not equal to the context."); } // calc the basekeys byte[] responseKeyLm; byte[] expectedNtChallengeResponse; byte[] expectedLmChallengeResponse; byte[] sessionBaseKey; byte[] keyExchangeKey; CalculateBaseKeys( authenticateInformation.ClientChallenge, this.systemTime, authenticateInformation.ServerName, authenticateInformation.DomainName, authenticateInformation.UserName, this.nlmpServer.Context.ClientCredential.Password, out responseKeyLm, out expectedNtChallengeResponse, out expectedLmChallengeResponse, out sessionBaseKey, out keyExchangeKey); // valid message ValidAuthenticateMessage(authenticatePacket, expectedNtChallengeResponse, expectedLmChallengeResponse); // generate keys. if (NlmpUtility.IsKeyExch(this.nlmpServer.Context.NegFlg)) { exportedSessionKey = NlmpUtility.RC4( keyExchangeKey, authenticatePacket.Payload.EncryptedRandomSessionKey); } else { exportedSessionKey = keyExchangeKey; } // validate mic byte[] messageMic = authenticatePacket.Payload.MIC; byte[] zeroMic = new byte[16]; if (messageMic != null && !ArrayUtility.CompareArrays <byte>(messageMic, zeroMic)) { AUTHENTICATE_MESSAGE payload = authenticatePacket.Payload; payload.MIC = zeroMic; authenticatePacket.Payload = payload; byte[] mic = NlmpUtility.GetMic(exportedSessionKey, this.negotiate, this.challenge, this.authenticate); if (!ArrayUtility.CompareArrays <byte>(messageMic, mic)) { throw new InvalidOperationException("mic of authenticate packet is invalid"); } } return(authenticateInformation); }
/// <summary> /// copy constructor. /// </summary> /// <param name="stackPacket">the source packet</param> /// <exception cref="ArgumentNullException">the stackPacket.payload.MIC must not be null</exception> /// <exception cref="ArgumentException">the stackPacket.payload.MIC.Length is wrong</exception> public NlmpAuthenticatePacket( NlmpAuthenticatePacket stackPacket ) : base(stackPacket) { this.payload = stackPacket.payload; if (stackPacket.payload.MIC == null) { throw new ArgumentNullException("stackPacket", "the stackPacket.payload.MIC must not be null"); } if (stackPacket.payload.MIC.Length != NlmpUtility.AUTHENTICATE_MESSAGE_MIC_CONST_SIZE) { throw new ArgumentException( string.Format("the stackPacket.payload.MIC.Length must be {0}, actually {1}", NlmpUtility.AUTHENTICATE_MESSAGE_MIC_CONST_SIZE, stackPacket.payload.MIC.Length), "stackPacket"); } this.payload.MIC = new byte[stackPacket.payload.MIC.Length]; Array.Copy(stackPacket.payload.MIC, this.payload.MIC, stackPacket.payload.MIC.Length); if (stackPacket.payload.DomainName != null) { this.payload.DomainName = new byte[stackPacket.payload.DomainName.Length]; Array.Copy( stackPacket.payload.DomainName, this.payload.DomainName, stackPacket.payload.DomainName.Length); } if (stackPacket.payload.UserName != null) { this.payload.UserName = new byte[stackPacket.payload.UserName.Length]; Array.Copy( stackPacket.payload.UserName, this.payload.UserName, stackPacket.payload.UserName.Length); } if (stackPacket.payload.Workstation != null) { this.payload.Workstation = new byte[stackPacket.payload.Workstation.Length]; Array.Copy( stackPacket.payload.Workstation, this.payload.Workstation, stackPacket.payload.Workstation.Length); } if (stackPacket.payload.LmChallengeResponse != null) { this.payload.LmChallengeResponse = new byte[stackPacket.payload.LmChallengeResponse.Length]; Array.Copy( stackPacket.payload.LmChallengeResponse, this.payload.LmChallengeResponse, stackPacket.payload.LmChallengeResponse.Length); } if (stackPacket.payload.NtChallengeResponse != null) { this.payload.NtChallengeResponse = new byte[stackPacket.payload.NtChallengeResponse.Length]; Array.Copy( stackPacket.payload.NtChallengeResponse, this.payload.NtChallengeResponse, stackPacket.payload.NtChallengeResponse.Length); } if (stackPacket.payload.EncryptedRandomSessionKey != null) { this.payload.EncryptedRandomSessionKey = new byte[stackPacket.payload.EncryptedRandomSessionKey.Length]; Array.Copy( stackPacket.payload.EncryptedRandomSessionKey, this.payload.EncryptedRandomSessionKey, stackPacket.payload.EncryptedRandomSessionKey.Length); } }
/// <summary> /// read struct from bytes. All sub class override this to unmarshal itself. /// </summary> /// <param name="start">the start to read bytes</param> /// <param name="packetBytes">the bytes of struct</param> /// <returns>the read result, if success, return true.</returns> protected override bool ReadStructFromBytes( byte[] packetBytes, int start ) { AUTHENTICATE_MESSAGE authenticate = new AUTHENTICATE_MESSAGE(); authenticate.LmChallengeResponseFields = NlmpUtility.BytesToStruct <MESSAGE_FIELDS>( packetBytes, ref start); authenticate.NtChallengeResponseFields = NlmpUtility.BytesToStruct <MESSAGE_FIELDS>( packetBytes, ref start); authenticate.DomainNameFields = NlmpUtility.BytesToStruct <MESSAGE_FIELDS>( packetBytes, ref start); authenticate.UserNameFields = NlmpUtility.BytesToStruct <MESSAGE_FIELDS>( packetBytes, ref start); authenticate.WorkstationFields = NlmpUtility.BytesToStruct <MESSAGE_FIELDS>( packetBytes, ref start); authenticate.EncryptedRandomSessionKeyFields = NlmpUtility.BytesToStruct <MESSAGE_FIELDS>( packetBytes, ref start); authenticate.NegotiateFlags = (NegotiateTypes)NlmpUtility.BytesToStruct <uint>( packetBytes, ref start); authenticate.Version = NlmpUtility.BytesToStruct <VERSION>( packetBytes, ref start); authenticate.MIC = NlmpUtility.ReadBytes( packetBytes, ref start, NlmpUtility.AUTHENTICATE_MESSAGE_MIC_CONST_SIZE); int currentIndex = 0; while (currentIndex != start) { currentIndex = start; if (authenticate.DomainNameFields.Len != 0 && authenticate.DomainNameFields.BufferOffset == start) { authenticate.DomainName = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.DomainNameFields.Len); continue; } else if (authenticate.EncryptedRandomSessionKeyFields.Len != 0 && authenticate.EncryptedRandomSessionKeyFields.BufferOffset == start) { authenticate.EncryptedRandomSessionKey = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.EncryptedRandomSessionKeyFields.Len); continue; } else if (authenticate.LmChallengeResponseFields.Len != 0 && authenticate.LmChallengeResponseFields.BufferOffset == start) { authenticate.LmChallengeResponse = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.LmChallengeResponseFields.Len); continue; } else if (authenticate.NtChallengeResponseFields.Len != 0 && authenticate.NtChallengeResponseFields.BufferOffset == start) { authenticate.NtChallengeResponse = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.NtChallengeResponseFields.Len); continue; } else if (authenticate.UserNameFields.Len != 0 && authenticate.UserNameFields.BufferOffset == start) { authenticate.UserName = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.UserNameFields.Len); continue; } else if (authenticate.WorkstationFields.Len != 0 && authenticate.WorkstationFields.BufferOffset == start) { authenticate.Workstation = NlmpUtility.ReadBytes( packetBytes, ref start, authenticate.WorkstationFields.Len); continue; } else { break; } } this.payload = authenticate; return(true); }