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