schannel: refactor: reduce variable scopes, fix comment, fix indent

Refactor and simplify the Schannel code, primarily by reducing
duplicated buffer-management and credential-setup logic.

- split client certificate selection into get_client_cert() and SSPI
  credential acquisition into acquire_sspi_handle()
- introduce a struct sbuffer for encrypted/decrypted buffering
- Add ensure_encoding_size() and ensure_decoding_size() helpers to
  centralize buffer growth/realloc decisions
- Tighten variable scopes and tidy indentation/logging in the handshake
  and receive/decrypt loops.
- Update comments and adjusts some receive error-condition handling to
  better preserve buffered-data behavior.

Closes #20569
This commit is contained in:
Daniel Stenberg 2026-02-11 23:43:45 +01:00
parent df6f3ae60a
commit 10bb489b22
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 515 additions and 463 deletions

File diff suppressed because it is too large Load Diff

View File

@ -104,17 +104,19 @@ struct Curl_schannel_ctxt {
CtxtHandle ctxt_handle;
};
/* handle encoding/decoding buffers */
struct sbuffer {
size_t length;
size_t offset;
unsigned char *buffer;
};
struct schannel_ssl_backend_data {
struct sbuffer encdata;
struct sbuffer decdata;
struct Curl_schannel_cred *cred;
struct Curl_schannel_ctxt *ctxt;
SecPkgContext_StreamSizes stream_sizes;
size_t encdata_length, decdata_length;
size_t encdata_offset, decdata_offset;
unsigned char *encdata_buffer, *decdata_buffer;
/* encdata_is_incomplete: if encdata contains only a partial record that
cannot be decrypted without another recv() (that is, status is
SEC_E_INCOMPLETE_MESSAGE) then set this true. after an recv() adds
more bytes into encdata then set this back to false. */
unsigned long req_flags, ret_flags;
CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
struct schannel_renegotiate_state {
@ -128,6 +130,10 @@ struct schannel_ssl_backend_data {
BIT(use_alpn); /* true if ALPN is used for this connection */
BIT(use_manual_cred_validation); /* true if manual cred validation is used */
BIT(sent_shutdown);
/* encdata_is_incomplete: if encdata contains only a partial record that
cannot be decrypted without another recv() (that is, status is
SEC_E_INCOMPLETE_MESSAGE) then set this true. after recv() adds more
bytes into encdata then set this back to false. */
BIT(encdata_is_incomplete);
};