Exemple #1
0
        // Section 3.3.2
        //
        // Set LmChallengeResponse to ConcatenationOf(
        //                              HMAC_MD5(ResponseKeyLM, ConcatenationOf(CHALLENGE_MESSAGE.ServerChallenge, ClientChallenge)),
        //                              ClientChallenge )
        private int makeLm2ChallengeResponse(byte[] lm2Hash, ReadOnlySpan <byte> serverChallenge, Span <byte> clientChallenge, ref Span <byte> responseAsBytes)
        {
            Debug.Assert(serverChallenge.Length == ChallengeLength);
            Debug.Assert(clientChallenge.Length == ChallengeLength);
            Debug.Assert(lm2Hash.Length == DigestLength);

            Span <AuthenticateMessage> response = MemoryMarshal.Cast <byte, AuthenticateMessage>(responseAsBytes);

            // Get server and client nonce
            Span <byte> blob = stackalloc byte[16];

            serverChallenge.CopyTo(blob);
            clientChallenge.CopyTo(blob.Slice(ChallengeLength));

            Span <byte> lmResponse = responseAsBytes.Slice((int)Marshal.OffsetOf(typeof(AuthenticateMessage), "LmResponse"), ChallengeResponseLength);

            HMACMD5 hmac   = new HMACMD5(lm2Hash);
            bool    result = hmac.TryComputeHash(blob, lmResponse, out int bytes);

            if (!result || bytes != DigestLength)
            {
                return(0);
            }

            clientChallenge.CopyTo(lmResponse.Slice(DigestLength));
            SetField(ref response[0].LmChallengeResponse, ChallengeResponseLength, (int)Marshal.OffsetOf(typeof(AuthenticateMessage), "LmResponse"));

            return(ChallengeResponseLength);
        }
Exemple #2
0
        // Section 3.3.2
        //
        // Set temp to ConcatenationOf(Responserversion, HiResponserversion, Z(6), Time, ClientChallenge, Z(4), ServerName, Z(4))
        // Set NTProofStr to HMAC_MD5(ResponseKeyNT, ConcatenationOf(CHALLENGE_MESSAGE.ServerChallenge, temp))
        // Set NtChallengeResponse to ConcatenationOf(NTProofStr, temp)
        private unsafe int makeNtlm2ChallengeResponse(byte[] lm2Hash, ReadOnlySpan <byte> serverChallenge, Span <byte> clientChallenge, ReadOnlySpan <byte> serverInfo, ref MessageField field, ref Span <byte> payload)
        {
            Debug.Assert(serverChallenge.Length == ChallengeLength);
            Debug.Assert(clientChallenge.Length == ChallengeLength);
            Debug.Assert(lm2Hash.Length == DigestLength);


            Span <byte> blob = payload.Slice(0, sizeof(NtChallengeResponse) + serverInfo.Length);
            Span <NtChallengeResponse> temp = MemoryMarshal.Cast <byte, NtChallengeResponse>(blob.Slice(0, sizeof(NtChallengeResponse)));

            temp[0].HiResponserversion = 1;
            temp[0].Responserversion   = 1;
            temp[0].Time = DateTime.Now.Ticks;

            int offset = (int)Marshal.OffsetOf(typeof(NtChallengeResponse), "ClientChallenge");

            clientChallenge.CopyTo(blob.Slice(offset, ChallengeLength));

            offset += ChallengeLength + 4; // challengeLength + Z4
            serverInfo.CopyTo(blob.Slice(offset));

            // We will prepend server chalenge for purpose of calculating NTProofStr
            // It will be overriten later.
            serverChallenge.CopyTo(blob.Slice(ChallengeLength, ChallengeLength));

            Span <byte> NTProofStr = stackalloc byte[DigestLength];
            HMACMD5     hmac       = new HMACMD5(lm2Hash);
            bool        result     = hmac.TryComputeHash(blob.Slice(ChallengeLength), NTProofStr, out int bytes);

            if (!result || bytes != DigestLength)
            {
                return(0);
            }

            // we created temp part in place where it needs to be.
            // now we need to prepend it with calculated hmac.
            // Write first 16 bytes, overiding challengeLength part.
            NTProofStr.CopyTo(blob);
            SetField(ref field, blob.Length, sizeof(AuthenticateMessage));

            payload = payload.Slice(blob.Length);
            return(blob.Length);
        }