JDK-8247311 : LDAP Channel Binding support for Java GSS/Kerberos
  • Type: CSR
  • Component: core-libs
  • Sub-Component: javax.naming
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 16
  • Submitted: 2020-06-10
  • Updated: 2024-07-09
  • Resolved: 2020-09-21
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Add support for LDAP Channel Binding information for Java GSS/Kerberos connection.

Problem
-------

Microsoft introduced a 'LdapEnforceChannelBinding' option requiring clients to provide channel binding information in order to connect to AD over SSL/TLS.

https://support.microsoft.com/en-au/help/4034879/how-to-add-the-ldapenforcechannelbinding-registry-entry

The current JDK implementation does not send required Channel Binding data to the server. As a result, LDAPS connection from an authenticated client that uses GSS fails.

Solution
--------

1. Add "com.sun.jndi.ldap.tls.cbtype" JNDI environment property indicating Channel Binding type required for connection. Possible value is:
- "tls-server-end-point" - Channel Binding data on the base of the server TLS certificate.
2. The following TLS Channel Binding types are specified in RFC-5929 but not supported:
- "tls-unique" is not supported.
- "tls-unique-for-telnet" is not applicable for LDAP connection.
3. The Channel Binding data is created according to the following specifications:
- RFC-5929 "Channel Bindings for TLS". Section 4 describes the encoding of the TLS Channel Binding data
- RFC-5056 "On the Use of Channel Bindings to Secure Channels". Section 2.1 describes the prefix encoding for different channel binding types.
- RFC-4121. Section 4.1.1.2 describes format end encoding of Channel Binding data for GSS/Kerberos
- "NTLM and Channel Binding Hash" document. This document describes values and encoding of the initiator/acceptor addresses and address type values.
4. The Windows LDAP server with LdapEnforceChannelBinding=2 uses the tls-server-end-point channel binding (based on the TLS server certificate). The channel binding data is calculated as follows:
- Implementation calculates a hash of the TLS server certificate. The hash algorithm is selected on the base of the certificate signature algorithm. Also, the implementation should use SHA-256 algorithm, in case of the certificate signature algorithm is SHA1 or MD5 based
- Implementation adds name of the Channel Binding type and colon (ASCII 0x3A) before the hash.
- Initiator and acceptor addresses should be set to NULL
- Initiator and acceptor address types should be zero. It contradicts the "Using Channel Bindings in GSS-API" document that says that the address type should be set to GSS_C_AF_NULLADDR=0xFF, instead of GSS_C_AF_UNSPEC=0x00. The implementation ensures that the changes in address type are applied to the TLS Channel Binding data only requested by "com.sun.jndi.ldap.tls.cbtype" property.

Links to the documents:

- RFC-5929 "Channel Bindings for TLS":
https://www.ietf.org/rfc/rfc5929.txt

- RFC-5056 "On the Use of Channel Bindings to Secure Channels":
https://www.ietf.org/rfc/rfc5056.txt

- RFC-4121 "The Kerberos Version 5 Generic Security Service Application Program Interface (GSS-API) Mechanism: Version 2":
https://www.ietf.org/rfc/rfc4121.txt

- "NTLM and Channel Binding Hash": https://docs.microsoft.com/en-us/archive/blogs/openspecification/ntlm-and-channel-binding-hash-aka-extended-protection-for-authentication

- "Using Channel Bindings in GSS-API": 
https://docs.oracle.com/cd/E19120-01/open.solaris/819-2145/overview-52/index.html

- Webrev: http://cr.openjdk.java.net/~abakhtin/8245527/webrev.v14/

Specification
-------------
Add the following section into src/java.naming/share/classes/module-info.java

    *     <li>{@code com.sun.jndi.ldap.tls.cbtype}:
    *         <br>The value of this property is the string representing the TLS
    *         Channel Binding type required for an LDAP connection over SSL/TLS.
    *         Possible value is :
    *         <ul>
    *             <li>"tls-server-end-point" - Channel Binding data is created on
    *                 the basis of the TLS server certificate.
    *             </li>
    *         </ul>
    *         <br>"tls-unique" TLS Channel Binding type is specified in RFC-5929
    *         but not supported.
    *         <br>If this property is not specified, the client does not send
    *         channel binding information to the server.
    *     </li>

Comments
[~abakhtin], as a general comment usually specification changes to java.* APIs are *not* made in update releases since that would require a maintenance review of the Java SE platform spec. However, this change is carefully constrained only apply to the JDK implementation rather than the Java SE specification, so it would be an acceptable update. Note that the on-line docs are not necessarily regenerated for update releases so if this change is made in an update, it may not appear in the on-line docs without some extra prodding.
23-09-2020

Yes, I'd like to backport it to JDK 15, JDK13, JDK11 and JDK8
22-09-2020

Moving to Approved for JDK 16. Is there some kind of backport plan for this change?
21-09-2020

The main goal of this feature is to provide LDAP Channel Binding support required for Windows LDAP server with LdapEnforceChannelBinding=2. Windows LDAP server in the LdapEnforceChannelBinding=2 configuration requires the tls-server-end-point channel binding type only. It means tls-unque implementation can not be verified. Also, there are some issues with tls-unique channel binding type: - There is no java public API to get the TLS Finished message required by "tls-unique”. It means this CB type can be implemented for SunJSSE TLS implementation only using internal API; - According to https://tools.ietf.org/html/rfc8446#appendix-C.5 tls-unique is not defined for TLS 1.3 which makes tls-unique CB type implementation incompatible for different TLS protocols. I can change the wording for tls-unque CB type if required
17-08-2020

Hopefully Alexey will be able to provide more details. My understanding is that the RFCs define two different modes and we only support one. Maybe the wording "Not supported right now" could be improved.
17-08-2020

Moving to Provisional, not Approved. I don't understand the intention of "tls-unique -- Not supported right now." Presumably it should be supported before the request is finalized!
14-08-2020