3.1.5.1.2 Client Receives a CHALLENGE_MESSAGE from the Server

When the client receives a CHALLENGE_MESSAGE (section 2.2.1.2) from the server, it MUST determine if the features selected by the server are strong enough for the client authentication policy. If not, the client MUST return an error to the calling application. Otherwise, the client responds with an AUTHENTICATE_MESSAGE (section 2.2.1.3).

If ClientRequire128bitEncryption == TRUE, then if 128-bit encryption is not negotiated, then the client MUST return SEC_E_UNSUPPORTED_FUNCTION ([MS-ERREF] section 2.1.1) to the application.

The client processes the CHALLENGE_MESSAGE and constructs an AUTHENTICATE_MESSAGE per the following pseudo code where all strings are encoded as RPC_UNICODE_STRING ([MS-DTYP] section 2.3.10):

 -- Input: 
 --   ClientConfigFlags, User, and UserDom - Defined in section 3.1.1.
 --   NbMachineName - The NETBIOS machine name of the server.
 --   An NTLM NEGOTIATE_MESSAGE whose fields are defined in
      section 2.2.1.1.
 --   An NTLM CHALLENGE_MESSAGE whose message fields are defined in 
      section 2.2.1.2. 
 --   An NTLM AUTHENTICATE_MESSAGE whose message fields are
      defined in section 2.2.1.3 with MIC field set to 0.
 --   OPTIONAL ClientSuppliedTargetName - Defined in section 3.1.1.2
 --   OPTIONAL ClientChannelBindingUnhashed - Defined in section 3.1.1.2
 --
 -- Output: 
 --   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
 --   An NTLM AUTHENTICATE_MESSAGE whose message fields are defined in
      section 2.2.1.3.
 --
 --   The following NTLM keys generated by the client 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. 
 --   Time - Temporary variable used to hold the 64-bit time.
 --   MIC - message integrity for the NTLM NEGOTIATE_MESSAGE,
      CHALLENGE_MESSAGE and AUTHENTICATE_MESSAGE  
 --
 -- Functions used:
 --   NTOWFv1, LMOWFv1, NTOWFv2, LMOWFv2, ComputeResponse - Defined in
      section 3.3
 --   KXKEY, SIGNKEY, SEALKEY - Defined in sections 3.4.5, 3.4.6, 
      and 3.4.7 
 --   Currenttime, NIL, NONCE - Defined in section 6.

Fields MUST be set as follows:

  • ChallengeFromClient to an 8-byte nonce.

  • UserName to User.

  • DomainName to UserDom.

  • Signature to the string "NTLMSSP".

  • MessageType to NtLmAuthenticate.

If the NTLMSSP_NEGOTIATE_VERSION flag is set by the client application, the Version field MUST be set to th11302e current version (section 2.2.2.10), and the Workstation field MUST be set to NbMachineName. Otherwise, if the NTLMSSP_NEGOTIATE_VERSION flag is not set by the client application, the Version field MUST be set to all-zero.

If NTLM v2 authentication is used, the client SHOULD send the timestamp in the CHALLENGE_MESSAGE.<47>

 If there exists a CHALLENGE_MESSAGE.TargetInfo.AvId ==
 MsvAvTimestamp
      Set Time to CHALLENGE_MESSAGE.TargetInfo.Value of that AVPair
 Else
      Set Time to Currenttime
 Endif
  

If NTLM v2 authentication is used and the CHALLENGE_MESSAGE does not contain both MsvAvNbComputerName and MsvAvNbDomainName AVPairs and either Integrity is TRUE or Confidentiality is TRUE, then return STATUS_LOGON_FAILURE ([MS-ERREF] section 2.3.1).

If NTLM v2 authentication is used and the CHALLENGE_MESSAGE TargetInfo field (section 2.2.1.2) has an MsvAvTimestamp present, the client SHOULD NOT send the LmChallengeResponse and SHOULD send Z(24) instead.<48>

Response keys are computed using the ComputeResponse() function, as specified in section 3.3.

 Set AUTHENTICATE_MESSAGE.NtChallengeResponse, 
    AUTHENTICATE_MESSAGE.LmChallengeResponse, SessionBaseKey to 
 ComputeResponse(CHALLENGE_MESSAGE.NegotiateFlags, ResponseKeyNT, 
    ResponseKeyLM, CHALLENGE_MESSAGE.ServerChallenge, 
    ChallengeFromClient, Time, 
    CHALLENGE_MESSAGE.TargetInfo)
  
 Set KeyExchangeKey to KXKEY(SessionBaseKey, LmChallengeResponse,
     CHALLENGE_MESSAGE.ServerChallenge)
 If (NTLMSSP_NEGOTIATE_KEY_EXCH bit is set in 
 CHALLENGE_MESSAGE.NegotiateFlags
   AND (NTLMSSP_NEGOTIATE_SIGN OR NTLMSSP_NEGOTIATE_SEAL are set in
 CHALLENGE_MESSAGE.NegotiateFlags))
      Set ExportedSessionKey to NONCE(16)
      Set AUTHENTICATE_MESSAGE.EncryptedRandomSessionKey to 
      RC4K(KeyExchangeKey, ExportedSessionKey)
 Else 
      Set ExportedSessionKey to KeyExchangeKey
      Set AUTHENTICATE_MESSAGE.EncryptedRandomSessionKey to NIL
 Endif
  
 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)
  
 Set MIC to HMAC_MD5(ExportedSessionKey, ConcatenationOf(
    NEGOTIATE_MESSAGE, CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE))
 Set AUTHENTICATE_MESSAGE.MIC to MIC
  

If the CHALLENGE_MESSAGE TargetInfo field has an MsvAvTimestamp present, the client SHOULD provide a MIC:<49>

  • If there is an AV_PAIR structure (section 2.2.2.1) with the AvId field set to MsvAvFlags,

    • then in the Value field, set bit 0x2 to 1.

    • else add an AV_PAIR structure and set the AvId field to MsvAvFlags and the Value field bit 0x2 to 1.

  • Populate the MIC field with the MIC.

The client SHOULD send the channel binding AV_PAIR <50>:

  • If the CHALLENGE_MESSAGE contains a TargetInfo field

    • If the ClientChannelBindingsUnhashed (section 3.1.1.2) is not NULL

      • Add an AV_PAIR structure and set the AvId field to MsvAvChannelBindings and the Value field to MD5_HASH(ClientChannelBindingsUnhashed).

      • Else add an AV_PAIR structure and set the AvId field to MsvAvChannelBindings and the Value field to Z(16).

    • If ClientSuppliedTargetName (section 3.1.1.2) is not NULL

      • Add an AV_PAIR structure and set the AvId field to MsvAvTargetName and the Value field to ClientSuppliedTargetName without terminating NULL. If UnverifiedTargetName (section 3.1.1.2) is TRUE, then in AvId field = MsvAvFlags set 0x00000004 bit.<51>

      • Else add an AV_PAIR structure and set the AvId field to MsvAvTargetName and the Value field to an empty string without terminating NULL.

When this process is complete, the client MUST send the AUTHENTICATE_MESSAGE to the server, embedded in an application protocol message, and encoded as specified by that application protocol.