Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/ntlm_auth/compute_keys.py: 23%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

44 statements  

1# Copyright: (c) 2018, Jordan Borean (@jborean93) <jborean93@gmail.com> 

2# MIT License (see LICENSE or https://opensource.org/licenses/MIT) 

3 

4import hashlib 

5import hmac 

6 

7from ntlm_auth.des import DES 

8from ntlm_auth.constants import NegotiateFlags 

9 

10 

11def _get_exchange_key_ntlm_v1(negotiate_flags, session_base_key, 

12 server_challenge, lm_challenge_response, 

13 lm_hash): 

14 """ 

15 [MS-NLMP] v28.0 2016-07-14 

16 

17 3.4.5.1 KXKEY 

18 Calculates the Key Exchange Key for NTLMv1 authentication. Used for signing 

19 and sealing messages 

20 

21 :param negotiate_flags: The negotiated NTLM flags 

22 :param session_base_key: A session key calculated from the user password 

23 challenge 

24 :param server_challenge: A random 8-byte response generated by the server 

25 in the CHALLENGE_MESSAGE 

26 :param lm_challenge_response: The LmChallengeResponse value computed in 

27 ComputeResponse 

28 :param lm_hash: The LMOWF computed in Compute Response 

29 :return: The Key Exchange Key (KXKEY) used to sign and seal messages and 

30 compute the ExportedSessionKey 

31 """ 

32 if negotiate_flags & \ 

33 NegotiateFlags.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 

34 key_exchange_key = hmac.new( 

35 session_base_key, server_challenge + lm_challenge_response[:8], 

36 digestmod=hashlib.md5 

37 ).digest() 

38 elif negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_LM_KEY: 

39 des_handler = DES(DES.key56_to_key64(lm_hash[:7])) 

40 first_des = des_handler.encrypt(lm_challenge_response[:8]) 

41 

42 second_des_key = lm_hash[7:8] + b"\xbd\xbd\xbd\xbd\xbd\xbd" 

43 des_handler = DES(DES.key56_to_key64(second_des_key)) 

44 second_des = des_handler.encrypt(lm_challenge_response[:8]) 

45 

46 key_exchange_key = first_des + second_des 

47 elif negotiate_flags & NegotiateFlags.NTLMSSP_REQUEST_NON_NT_SESSION_KEY: 

48 key_exchange_key = lm_hash[:8] + b'\0' * 8 

49 else: 

50 key_exchange_key = session_base_key 

51 

52 return key_exchange_key 

53 

54 

55def _get_exchange_key_ntlm_v2(session_base_key): 

56 """ 

57 [MS-NLMP] v28.0 2016-07-14 

58 

59 4.3.5.1 KXKEY 

60 Calculates the Key Exchange Key for NTLMv2 authentication. Used for signing 

61 and sealing messages. According to docs, 'If NTLM v2 is used, 

62 KeyExchangeKey MUST be set to the given 128-bit SessionBaseKey 

63 

64 :param session_base_key: A session key calculated from the user password 

65 challenge 

66 :return key_exchange_key: The Key Exchange Key (KXKEY) used to sign and 

67 seal messages 

68 """ 

69 return session_base_key 

70 

71 

72def get_sign_key(exported_session_key, magic_constant): 

73 """ 

74 3.4.5.2 SIGNKEY 

75 

76 :param exported_session_key: A 128-bit session key used to derive signing 

77 and sealing keys 

78 :param magic_constant: A constant value set in the MS-NLMP documentation 

79 (constants.SignSealConstants) 

80 :return sign_key: Key used to sign messages 

81 """ 

82 

83 sign_key = hashlib.md5(exported_session_key + magic_constant).digest() 

84 

85 return sign_key 

86 

87 

88def get_seal_key(negotiate_flags, exported_session_key, magic_constant): 

89 """ 

90 3.4.5.3. SEALKEY 

91 Main method to use to calculate the seal_key used to seal (encrypt) 

92 messages. This will determine the correct method below to use based on the 

93 compatibility flags set and should be called instead of the others 

94 

95 :param exported_session_key: A 128-bit session key used to derive signing 

96 and sealing keys 

97 :param negotiate_flags: The negotiate_flags structure sent by the server 

98 :param magic_constant: A constant value set in the MS-NLMP documentation 

99 (constants.SignSealConstants) 

100 :return seal_key: Key used to seal messages 

101 """ 

102 

103 if negotiate_flags & \ 

104 NegotiateFlags.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: 

105 seal_key = _get_seal_key_ntlm2(negotiate_flags, 

106 exported_session_key, 

107 magic_constant) 

108 elif negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_LM_KEY: 

109 seal_key = _get_seal_key_ntlm1(negotiate_flags, exported_session_key) 

110 else: 

111 seal_key = exported_session_key 

112 

113 return seal_key 

114 

115 

116def _get_seal_key_ntlm1(negotiate_flags, exported_session_key): 

117 """ 

118 3.4.5.3 SEALKEY 

119 Calculates the seal_key used to seal (encrypt) messages. This for 

120 authentication where NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY has not 

121 been negotiated. Will weaken the keys if NTLMSSP_NEGOTIATE_56 is not 

122 negotiated it will default to the 40-bit key 

123 

124 :param negotiate_flags: The negotiate_flags structure sent by the server 

125 :param exported_session_key: A 128-bit session key used to derive signing 

126 and sealing keys 

127 :return seal_key: Key used to seal messages 

128 """ 

129 if negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_56: 

130 seal_key = exported_session_key[:7] + b"\xa0" 

131 else: 

132 seal_key = exported_session_key[:5] + b"\xe5\x38\xb0" 

133 

134 return seal_key 

135 

136 

137def _get_seal_key_ntlm2(negotiate_flags, exported_session_key, magic_constant): 

138 """ 

139 3.4.5.3 SEALKEY 

140 Calculates the seal_key used to seal (encrypt) messages. This for 

141 authentication where NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY has been 

142 negotiated. Will weaken the keys if NTLMSSP_NEGOTIATE_128 is not 

143 negotiated, will try NEGOTIATE_56 and then will default to the 40-bit key 

144 

145 :param negotiate_flags: The negotiate_flags structure sent by the server 

146 :param exported_session_key: A 128-bit session key used to derive signing 

147 and sealing keys 

148 :param magic_constant: A constant value set in the MS-NLMP documentation 

149 (constants.SignSealConstants) 

150 :return seal_key: Key used to seal messages 

151 """ 

152 if negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_128: 

153 seal_key = exported_session_key 

154 elif negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_56: 

155 seal_key = exported_session_key[:7] 

156 else: 

157 seal_key = exported_session_key[:5] 

158 

159 seal_key = hashlib.md5(seal_key + magic_constant).digest() 

160 

161 return seal_key