TLS 1.3 does not work (fails after a second SEC_I_RENEGOTIATE)
Closed this issue · 0 comments
kobykahane commented
When running the testcase tls_13
on my Windows 11 (24H2) system, and also on a Windows Server 2022 VM, I get the following failure:
D:\source\schannel-rs>cargo test tls_13
<snip>
running 1 test
test test::tls_13 ... FAILED
failures:
---- test::tls_13 stdout ----
thread 'test::tls_13' panicked at src\test.rs:293:34:
called `Result::unwrap()` on an `Err` value: Os { code: -2146893033, kind: Uncategorized, message: "The context has expired and can no longer be used." }
stack backtrace:
0: std::panicking::begin_panic_handler
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\std\src\panicking.rs:665
1: core::panicking::panic_fmt
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\core\src\panicking.rs:74
2: core::result::unwrap_failed
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\core\src\result.rs:1679
3: enum2$<core::result::Result<usize,std::io::error::Error> >::unwrap
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c\library\core\src\result.rs:1102
4: schannel::test::tls_13
at .\src\test.rs:293
5: schannel::test::tls_13::closure$0
at .\src\test.rs:275
6: core::ops::function::FnOnce::call_once<schannel::test::tls_13::closure_env$0,tuple$<> >
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c\library\core\src\ops\function.rs:250
7: core::ops::function::FnOnce::call_once
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\core\src\ops\function.rs:250
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
failures:
test::tls_13
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 41 filtered out; finished in 0.10s
error: test failed, to rerun pass `--lib`
where -2146893033
is SEC_E_CONTEXT_EXPIRED
.
After adding the following debug prints:
diff --git a/src/tls_stream.rs b/src/tls_stream.rs
index 6f59f21..3d00ad1 100644
--- a/src/tls_stream.rs
+++ b/src/tls_stream.rs
@@ -487,6 +487,7 @@ where
_ => ptr::null_mut(),
};
+ println!("Calling InitializeSecurityContextW");
Identity::InitializeSecurityContextW(
&self.cred.as_inner(),
self.context.get_mut(),
@@ -835,6 +836,7 @@ where
];
let bufdesc = secbuf_desc(&mut bufs);
+ println!("Calling DecryptMessage");
match Identity::DecryptMessage(self.context.get_mut(), &bufdesc, 0, ptr::null_mut()) {
Foundation::SEC_E_OK => {
let start = bufs[1].pvBuffer as usize - self.enc_in.get_ref().as_ptr() as usize;
@@ -865,6 +867,7 @@ where
}
Foundation::SEC_I_CONTEXT_EXPIRED => Ok(true),
Foundation::SEC_I_RENEGOTIATE => {
+ println!("Got SEC_I_RENEGOTIATE");
self.state = State::Initializing {
needs_flush: false,
more_calls: true,
I see the following:
D:\source\schannel-rs>cargo test tls_13 -- --nocapture
<snip>
running 1 test
Calling InitializeSecurityContextW
Calling InitializeSecurityContextW
Calling InitializeSecurityContextW
Calling DecryptMessage
Got SEC_I_RENEGOTIATE
Calling InitializeSecurityContextW
Calling DecryptMessage
Got SEC_I_RENEGOTIATE
Calling DecryptMessage
thread 'test::tls_13' panicked at src\test.rs:293:34:
called `Result::unwrap()` on an `Err` value: Os { code: -2146893033, kind: Uncategorized, message: "The context has expired and can no longer be used." }
<snip>
Apparently indicating that InitializeSecurityContext
was not called again after the second SEC_I_RENEGOTIATE
, which I believe is necessary according to https://learn.microsoft.com/en-us/windows/win32/secauthn/recognizing-a-request-to-renegotiate-a-connection.