Example #1
0
        /// <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;
        }
Example #4
0
        /// <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);
        }