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>