1 package org.metricshub.winrm.service.client.auth.ntlm;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.util.Arrays;
24 import org.metricshub.winrm.service.client.encryption.ByteArrayUtils;
25 import org.metricshub.winrm.service.client.encryption.EncryptionUtils;
26
27
28
29
30
31 public class NtlmKeys {
32
33
34
35
36
37
38
39 private static final byte[] CLIENT_SIGNING =
40 "session key to client-to-server signing key magic constant\0".getBytes();
41 private static final byte[] SERVER_SIGNING =
42 "session key to server-to-client signing key magic constant\0".getBytes();
43 private static final byte[] CLIENT_SEALING =
44 "session key to client-to-server sealing key magic constant\0".getBytes();
45 private static final byte[] SERVER_SEALING =
46 "session key to server-to-client sealing key magic constant\0".getBytes();
47
48 private final byte[] exportedSessionKey;
49 private final long negotiateFlags;
50
51 public NtlmKeys(final Type3Message signAndSealData) {
52 exportedSessionKey = signAndSealData.getExportedSessionKey();
53 negotiateFlags = signAndSealData.getType2Flags();
54 }
55
56 public void apply(final NTCredentialsWithEncryption credentials) {
57 credentials.setNegotiateFlags(negotiateFlags);
58
59 credentials.setClientSigningKey(getSignKey(CLIENT_SIGNING));
60 credentials.setServerSigningKey(getSignKey(SERVER_SIGNING));
61 credentials.setClientSealingKey(getSealKey(CLIENT_SEALING));
62 credentials.setServerSealingKey(getSealKey(SERVER_SEALING));
63 }
64
65
66
67
68
69
70
71 private byte[] getSignKey(final byte[] magicConstant) {
72 return EncryptionUtils.md5digest(ByteArrayUtils.concat(exportedSessionKey, magicConstant));
73 }
74
75
76
77
78
79
80
81
82
83
84 private byte[] getSealKey(final byte[] magicConstant) {
85
86
87
88 if (hasNegotiateFlag(NTLMEngineUtils.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)) {
89 if (hasNegotiateFlag(NTLMEngineUtils.NTLMSSP_NEGOTIATE_128)) {
90 return EncryptionUtils.md5digest(ByteArrayUtils.concat(exportedSessionKey, magicConstant));
91 }
92 if (hasNegotiateFlag(NTLMEngineUtils.NTLMSSP_NEGOTIATE_56)) {
93 return EncryptionUtils.md5digest(
94 ByteArrayUtils.concat(Arrays.copyOfRange(exportedSessionKey, 0, 7), magicConstant)
95 );
96 }
97 return EncryptionUtils.md5digest(
98 ByteArrayUtils.concat(Arrays.copyOfRange(exportedSessionKey, 0, 5), magicConstant)
99 );
100 }
101
102
103
104
105 if (hasNegotiateFlag(NTLMEngineUtils.NTLMSSP_NEGOTIATE_LM_KEY)) {
106 throw new UnsupportedOperationException(
107 "LM KEY negotiate mode not implemented; use extended session security instead"
108 );
109 }
110
111 return exportedSessionKey;
112 }
113
114 private boolean hasNegotiateFlag(long flag) {
115 return (negotiateFlags & flag) == flag;
116 }
117 }