You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5b2b137
Browse filesBrowse the repository at this point in the historyBrowse files
fix(ntlm): preserve RC4 sealing state across mechListMIC (#753)
CredSSP can wrap `pubKeyAuth` after the initiator sends its mechListMIC
but before it verifies the acceptor's MIC. Resetting both NTLM RC4
handles during verification loses the advanced send state and breaks the
next wrapped message.
Snapshot and restore only the sealing handle used for each MIC,
including when verification fails. Remove the obsolete reset helper and
add regression coverage for both directions, the CredSSP ordering, and
invalid signatures. Sequence numbers remain unchanged.
Tests: `cargo test -p sspi --lib ntlm::test:: --quiet` (36 passed);
`cargo test -p sspi --features network_client,__test-data --test sspi
ntlm --quiet` (14 passed); `cargo check -p sspi --quiet`; `cargo fmt
--all --check`.
Fixes: #752
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: src/ntlm/mod.rs
+10-83Lines changed: 10 additions & 83 deletions
Original file line number
Diff line number
Diff line change
@@ -99,8 +99,6 @@ pub struct Ntlm {
99
99
// If the NTLM is used as server, then our_seq_number is the server sequence number and remote seq_number is the client sequence number.
100
100
our_seq_number:u32,
101
101
remote_seq_number:u32,
102
-
// This flag is needed to correctly reset cipher state after MIC token generation/verification.
103
-
is_client:bool,
104
102
105
103
session_key:Option<[u8;SESSION_KEY_SIZE]>,
106
104
}
@@ -162,7 +160,6 @@ impl Ntlm {
162
160
163
161
our_seq_number:0,
164
162
remote_seq_number:0,
165
-
is_client:true,
166
163
}
167
164
}
168
165
@@ -194,7 +191,6 @@ impl Ntlm {
194
191
195
192
our_seq_number:0,
196
193
remote_seq_number:0,
197
-
is_client:true,
198
194
}
199
195
}
200
196
@@ -226,7 +222,6 @@ impl Ntlm {
226
222
227
223
our_seq_number:0,
228
224
remote_seq_number:0,
229
-
is_client:true,
230
225
}
231
226
}
232
227
@@ -252,47 +247,6 @@ impl Ntlm {
252
247
});
253
248
}
254
249
255
-
/// Resets the cipher state.
256
-
///
257
-
/// According to the specification, we need to reset ciphers before and after MIC token generation/verification.
258
-
/// [3.2.5.1 NTLM RC4 Key State for MechListMIC and First Signed Message](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-spng/f38ae8e3-847d-4829-b933-5ac1911a00ba):
259
-
/// > When NTLM is negotiated, the SPNG server MUST set OriginalHandle to ServerHandle before generating the mechListMIC,
260
-
/// > then set ServerHandle to OriginalHandle after generating the mechListMIC. This results in the RC4 key state
261
-
/// > being the same for the mechListMIC and for the first message signed by the application.
262
-
/// >
263
-
/// > Because the RC4 key state is the same for the mechListMIC and for the first message signed by the application,
264
-
/// > the SPNEGO Extension server MUST set OriginalHandle to ClientHandle before validating the mechListMIC and then
265
-
/// > set ClientHandle to OriginalHandle after validating the mechListMIC.
// We reset the cipher state before and after MIC token verification.
807
-
//
808
-
// [3.2.5.1 NTLM RC4 Key State for MechListMIC and First Signed Message](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-spng/f38ae8e3-847d-4829-b933-5ac1911a00ba):
809
-
// > When NTLM is negotiated, the SPNG server MUST set OriginalHandle to ServerHandle before generating the mechListMIC,
810
-
// > then set ServerHandle to OriginalHandle after generating the mechListMIC. This results in the RC4 key state
811
-
// > being the same for the mechListMIC and for the first message signed by the application.
812
-
// >
813
-
// > Because the RC4 key state is the same for the mechListMIC and for the first message signed by the application,
814
-
// > the SPNEGO Extension server MUST set OriginalHandle to ClientHandle before validating the mechListMIC and then
815
-
// > set ClientHandle to OriginalHandle after validating the mechListMIC.
816
-
817
756
ifself.recv_sealing_key.is_none(){
818
757
self.complete_auth_token(&mut[])?;
819
-
}else{
820
-
self.reset_cipher_state()?;
821
758
}
822
759
823
760
let seq_number = self.remote_seq_num();
824
761
825
762
let digest = compute_digest(self.recv_signing_key.as_ref(), seq_number, data)?;
// We reset the cipher state before and after MIC token generation.
835
-
//
836
-
// [3.2.5.1 NTLM RC4 Key State for MechListMIC and First Signed Message](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-spng/f38ae8e3-847d-4829-b933-5ac1911a00ba):
837
-
// > When NTLM is negotiated, the SPNG server MUST set OriginalHandle to ServerHandle before generating the mechListMIC,
838
-
// > then set ServerHandle to OriginalHandle after generating the mechListMIC. This results in the RC4 key state
839
-
// > being the same for the mechListMIC and for the first message signed by the application.
840
-
// >
841
-
// > Because the RC4 key state is the same for the mechListMIC and for the first message signed by the application,
842
-
// > the SPNEGO Extension server MUST set OriginalHandle to ClientHandle before validating the mechListMIC and then
843
-
// > set ClientHandle to OriginalHandle after validating the mechListMIC.
0 commit comments