On Mon, 9 Nov 2026 19:47:26 GMT, Alexey Bakhtin <[email protected]> wrote:

>> Please review a fix that makes the SSPI bridge pass channel bindings to 
>> `InitializeSecurityContext`.
>> 
>> `gss_init_sec_context` in `sspi.cpp` receives `input_chan_bindings`, but 
>> never passes a `SECBUFFER_CHANNEL_BINDINGS` buffer to 
>> `InitializeSecurityContext`. A server that requires channel binding (for 
>> example IIS with Extended Protection "Always") rejects the Kerberos token, 
>> and the client gets 401.
>> 
>> The patch adds `convert_chan_bindings`. It builds a `SEC_CHANNEL_BINDINGS` 
>> blob from `input_chan_bindings` and passes it as an extra input buffer on 
>> every call, unless the caller passes `GSS_C_NO_CHANNEL_BINDINGS`.
>> 
>> The patch proposed in the bug report fails with `SEC_E_UNSUPPORTED_FUNCTION` 
>> when either address is non-empty. This patch copies the initiator and 
>> acceptor address types and bytes into the structure instead, for two reasons:
>> 
>> - The built-in TLS binding (`TlsChannelBindingImpl`) has no addresses (type 
>> 0, empty). But `org.ietf.jgss.ChannelBinding(InetAddress, InetAddress, 
>> byte[])` is public API, so applications can set addresses. The pure-Java 
>> Kerberos initiator supports that, and rejecting it would make the native 
>> bridge behave differently.
>> - The Kerberos checksum carries an MD5 over the address types, lengths, 
>> address bytes and application data (RFC 4121 section 4.1.1.2). The acceptor 
>> hashes whatever it was given, so dropping the addresses would make the 
>> hashes differ.
>> 
>> The address type is copied even when the address is empty, because it is 
>> part of the hash. TLS uses 0 and other bindings use `GSS_C_AF_NULLADDR` 
>> (255). These are set by `newGSSCB`.
>> 
>> **Testing.**
>> Verified on a non-domain-joined Windows 11 machine. An MIT KDC (realm 
>> TEST.LOCAL) runs in WSL. A Java HTTPS server (Java GSS, SPN 
>> `HTTP/host.test.local`) enforces channel binding with the 
>> `tls-server-end-point` hash of its certificate, to mimic IIS Extended 
>> Protection "Always". The client is `HttpsURLConnection`, started with `runas 
>> /netonly`, `-Dsun.security.jgss.native=true` and 
>> `-Djdk.https.negotiate.cbt=always`. 
>> 
>> The client runs in three modes:
>> (A) baseline, 
>> (B) A plus `-Djavax.security.auth.useSubjectCredsOnly=false`, 
>> (C) B with no Authenticator and a browser-style User-Agent, as in the bug 
>> report.
>> 
>> - Without the fix, all three failed with `GSSException: Channel binding 
>> mismatch (Mechanism level: Token missing ChannelBinding!)`.
>> - With the fix, all three passed (`Auth SUCCESS - client: 
>> [email protected]`).
>> 
>> ---------
>> - [X] I confir...
>
> Alexey Bakhtin has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Update copyright year in sspi.cpp

Thank you for the update.  LGTM.

-------------

Marked as reviewed by semery (Committer).

PR Review: https://git.openjdk.org/jdk/pull/33528#pullrequestreview-5853963661

Reply via email to