3.2.5.1.2 Server Receives an AUTHENTICATE_MESSAGE from the Client
Upon receipt of the embedded AUTHENTICATE_MESSAGE (section 2.2.1.3), the server MUST extract and decode the AUTHENTICATE_MESSAGE.
If ServerBlock is set to TRUE then the server MUST return STATUS_NOT_SUPPORTED ([MS-ERREF] section 2.3.1).<65>
If the user name and response are empty, the server authenticates the client as the ANONYMOUS user ([MS-DTYP] section 2.4.2.4). Regardless of whether or not the client is an ANONYMOUS user, if the security features selected by the client are not strong enough for the server security policy, the server MUST return an error to the calling application. Otherwise, the server obtains the response key by looking up the user name in a database. With the NT and LM responses keys and the client challenge, the server computes the expected response. If the expected response matches the actual response, then the server MUST generate session, signing, and sealing keys; otherwise, it MUST deny the client access.
NTLM servers SHOULD support NTLM clients which incorrectly use NIL for the UserDom for calculating ResponseKeyNT and ResponseKeyLM.
The keys MUST be computed with the following algorithm where all strings are encoded as RPC_UNICODE_STRING ([MS-DTYP] section 2.3.10).
-
-- Input: -- CHALLENGE_MESSAGE.ServerChallenge - The ServerChallenge field from the server CHALLENGE_MESSAGE in section 3.2.5.1.1 -- NegFlg - Defined in section 3.1.1. -- ServerName - The NETBIOS or the DNS name of the server. -- An NTLM NEGOTIATE_MESSAGE whose message fields are defined in section 2.2.1.1. -- An NTLM AUTHENTICATE_MESSAGE whose message fields are defined in section 2.2.1.3. --- An NTLM AUTHENTICATE_MESSAGE whose message fields are defined in section 2.2.1.3 with the MIC field set to 0. -- OPTIONAL ServerChannelBindingsUnhashed - Defined in section 3.2.1.2 ---- Output: Result of authentication -- ClientHandle - The handle to a key state structure corresponding -- to the current state of the ClientSealingKey -- ServerHandle - The handle to a key state structure corresponding -- to the current state of the ServerSealingKey -- The following NTLM keys generated by the server are defined in section 3.1.1: -- ExportedSessionKey, ClientSigningKey, ClientSealingKey, ServerSigningKey, and ServerSealingKey. ---- Temporary variables that do not pass over the wire are defined below: -- KeyExchangeKey, ResponseKeyNT, ResponseKeyLM, SessionBaseKey - Temporary variables used to store 128-bit keys. -- MIC - message integrity for the NTLM NEGOTIATE_MESSAGE, CHALLENGE_MESSAGE and AUTHENTICATE_MESSAGE -- MessageMIC - Temporary variable used to hold the original value of the MIC field to compare the computed value. -- Time - Temporary variable used to hold the 64-bit current time from the NTLMv2_CLIENT_CHALLENGE.Timestamp, in the format of a FILETIME as defined in [MS-DTYP] section 2.3.1. -- ChallengeFromClient – Temporary variable to hold the client's 8-byte challenge, if used. -- ExpectedNtChallengeResponse - Temporary variable to hold results returned from ComputeResponse. -- ExpectedLmChallengeResponse - Temporary variable to hold results returned from ComputeResponse. -- NullSession – Temporary variable to denote whether client has explicitly requested to be anonymously authenticated. ---- Functions used: -- ComputeResponse - Defined in section 3.3 -- KXKEY, SIGNKEY, SEALKEY - Defined in sections 3.4.5, 3.4.6, and 3.4.7 -- GetVersion(), NIL - Defined in section 6 Set NullSession to FALSE Set GuestSession to FALSE If (AUTHENTICATE_MESSAGE.UserNameLen == 0 AND AUTHENTICATE_MESSAGE.NtChallengeResponse.Length == 0 AND (AUTHENTICATE_MESSAGE.LmChallengeResponse == Z(1) OR AUTHENTICATE_MESSAGE.LmChallengeResponse.Length == 0)) -- Special case: client requested anonymous authentication Set NullSession to TRUE Else Retrieve the ResponseKeyNT and ResponseKeyLM from the local user account database using the UserName and DomainName specified in the AUTHENTICATE_MESSAGE. If AUTHENTICATE_MESSAGE.NtChallengeResponseFields.NtChallengeResponseLen > 0x0018 Set ChallengeFromClient to NTLMv2_RESPONSE.NTLMv2_CLIENT_CHALLENGE.ChallengeFromClient ElseIf NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is set in NegFlg Set ChallengeFromClient to LM_RESPONSE.Response[0..7] Else Set ChallengeFromClient to NIL EndIf Set ExpectedNtChallengeResponse, ExpectedLmChallengeResponse, SessionBaseKey to ComputeResponse(NegFlg, ResponseKeyNT, ResponseKeyLM, CHALLENGE_MESSAGE.ServerChallenge, ChallengeFromClient, Time, ServerName) Set KeyExchangeKey to KXKEY(SessionBaseKey, AUTHENTICATE_MESSAGE.LmChallengeResponse, CHALLENGE_MESSAGE.ServerChallenge) If (AUTHENTICATE_MESSAGE.NtChallengeResponse != ExpectedNtChallengeResponse) If (AUTHENTICATE_MESSAGE.LmChallengeResponse != ExpectedLmChallengeResponse) Retry using NIL for the domain name: Retrieve the ResponseKeyNT and ResponseKeyLM from the local user account database using the UserName specified in the AUTHENTICATE_MESSAGE and NIL for the DomainName. Set ExpectedNtChallengeResponse, ExpectedLmChallengeResponse, SessionBaseKey to ComputeResponse(NegFlg, ResponseKeyNT, ResponseKeyLM, CHALLENGE_MESSAGE.ServerChallenge, ChallengeFromClient, Time, ServerName) Set KeyExchangeKey to KXKEY(SessionBaseKey, AUTHENTICATE_MESSAGE.LmChallengeResponse, CHALLENGE_MESSAGE.ServerChallenge) If (AUTHENTICATE_MESSAGE.NtChallengeResponse != ExpectedNtChallengeResponse) If (AUTHENTICATE_MESSAGE.LmChallengeResponse !=
-
ExpectedLmChallengeResponse)
-
If (Guest user is not disabled AND Guest user has no password set AND UserName does not exist in user account database)
-
--Special case: User can be logged in as Guest user
-
Set GuestSession to TRUE
-
Else
-
Return INVALID message error EndIf EndIf EndIf EndIf EndIf EndIf Set MessageMIC to AUTHENTICATE_MESSAGE.MIC Set AUTHENTICATE_MESSAGE.MIC to Z(16) If (NTLMSSP_NEGOTIATE_KEY_EXCH flag is set in NegFlg AND (NTLMSSP_NEGOTIATE_SIGN OR NTLMSSP_NEGOTIATE_SEAL are set in NegFlg) ) Set ExportedSessionKey to RC4K(KeyExchangeKey, AUTHENTICATE_MESSAGE.EncryptedRandomSessionKey) Else Set ExportedSessionKey to KeyExchangeKey EndIf Set MIC to HMAC_MD5(ExportedSessionKey, ConcatenationOf( NEGOTIATE_MESSAGE, CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE)) Set ClientSigningKey to SIGNKEY(NegFlg, ExportedSessionKey , "Client") Set ServerSigningKey to SIGNKEY(NegFlg, ExportedSessionKey , "Server") Set ClientSealingKey to SEALKEY(NegFlg, ExportedSessionKey , "Client") Set ServerSealingKey to SEALKEY(NegFlg, ExportedSessionKey , "Server") RC4Init(ClientHandle, ClientSealingKey) RC4Init(ServerHandle, ServerSealingKey)
If NullSession is TRUE, the server authenticates the client as the ANONYMOUS user account (see [MS-DTYP] section 2.4.2.4).
If NullSession is TRUE, a SessionBaseKey with all-zeroes, Z(16), is used.
If GuestSession is TRUE, the server authenticates the client as the Guest user account (see [MS-DTYP] section 2.4.2.4).
If GuestSession is TRUE, a SessionBaseKey with all-zeroes, Z(16), is used.
If NTLMSSP_NEGOTIATE_KEY_EXCH is set, the server MUST check if client supplied a valid EncryptedRandomSessionKey in the AUTHENTICATE_MESSAGE (section 2.2.1.3); otherwise, the server MUST return SEC_E_INVALID_TOKEN.
If NTLM v2 authentication is used and channel binding is provided by the application, then the server MUST verify the channel binding:<66>
If ServerChannelBindingsUnhashed (section 3.2.1.2) is not NULL
If the AUTHENTICATE_MESSAGE contains a nonzero MsvAvChannelBindings AV_PAIR
If MD5_HASH(ServerChannelBindingsUnhashed) != MsvAvChannelBindings.AvPair.Value)
The server MUST return GSS_S_BAD_BINDINGS
Else the server MUST return GSS_S_BAD_BINDINGS
Else If ApplicationRequiresCBT (section 3.2.1.2) == TRUE
If the AUTHENTICATE_MESSAGE does not contain a nonzero MsvAvChannelBindings AV_PAIR
The server MUST return GSS_S_BAD_BINDINGS
If the AUTHENTICATE_MESSAGE contains an MsvAvTargetName
If the AUTHENTICATE_MESSAGE indicates the presence of a MIC field,<68> then the MIC value computed earlier MUST be compared to MessageMIC, and if the two MIC values are not equal, then an authentication failure MUST be returned. An AUTHENTICATE_MESSAGE indicates the presence of a MIC field if the TargetInfo field has an AV_PAIR structure whose two fields:
AvId == MsvAvFlags
Value bit 0x2 == 1
If NTLM v2 authentication is used and the AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp (section 2.2.2.7) is more than MaxLifetime (section 3.1.1.1) difference from the server time, then the server SHOULD return a failure.<69>
Both the client and the server now have the session, signing, and sealing keys. When the client runs an integrity check on the next message from the server, it detects that the server has determined (either directly or indirectly) the user password.
Note User names MUST be case-insensitive. For additional information about the case sensitivity of user names, see [MS-AUTHSOD] section 1.1.1.2.