JDK-8245527 : LDAP Channel Binding support for Java GSS/Kerberos
  • Type: Bug
  • Component: core-libs
  • Sub-Component: javax.naming
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-05-21
  • Updated: 2024-02-22
  • Resolved: 2020-09-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 13 JDK 15 JDK 16
11.0.11Fixed 13-poolResolved 15.0.9Fixed 16 b18Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8258824 :  
JDK-8280071 :  
Description
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

When the option is enabled in the AD, then LDAPS connections from an authenticated client that use GSS will fail, with a message similar to:

javax.naming.AuthenticationException: [LDAP: error code 49 - 80090346: LdapErr: DSID-0C09056D, comment: AcceptSecurityContext error, data 80090346, v2580

How to reproduce:
1. Test environment: 
    - Windows Server 2012 R2, with Active Directory, Enterprise CA, LDAPS enabled. 
    - Linux client : setup commands are attached
2. Enable Channel Binding Enforcement (value=2) on the Windows LDAP server : 
Windows Registry Editor Version 5.00


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters]
"LdapEnforceChannelBinding"=dword:00000002
Refer to the following instructions for more information : https://support.microsoft.com/en-in/help/4034879
2. Compile and run simple LDAP Client:
public class LdapChannelBindingWithGSSAPI1 {

    public static String LDAPS_URL="ldaps://something.com";
    public static String USER="user";
    public static String KRB5CONFIG_FILE = "krb5.conf";
    public static String JAASCONFIG_FILE = "jaas.conf";

    public static void main(String[] args) throws LoginException, NamingException {
        System.setProperty("java.security.krb5.conf", KRB5CONFIG_FILE);
        System.setProperty("java.security.auth.login.config", JAASCONFIG_FILE);
        System.setProperty("sun.security.krb5.principal", USER);

        LoginContext lc = new LoginContext("LdapChannelBinding", new TextCallbackHandler());
        lc.login();

        JndiAction jndiAction = new JndiAction();
        Subject.doAs(lc.getSubject(), jndiAction);
    }
}

class JndiAction implements java.security.PrivilegedAction {

    public Object run() {
        Hashtable env = new Hashtable();

        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, LdapChannelBindingWithGSSAPI1.LDAPS_URL);
        env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
        env.put("com.sun.jndi.ldap.tls.cbtype", "tls-server-end-point");
        env.put("com.sun.jndi.ldap.connect.timeout", "2000");

        try {
            //InitialDirContext initialDirContext = new InitialDirContext(env);
            InitialLdapContext initialDirContext = new InitialLdapContext(env, null);
            System.out.println(initialDirContext.getAttributes(""));
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

3. On success client authenticated to the server and prints attributes
Otherwise fails with "[LDAP: error code 49 - 80090346: LdapErr: DSID-0C09056D, comment: AcceptSecurityContext error, data 80090346, v2580]"
Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk15u-dev/pull/228 Date: 2022-07-12 09:11:23 +0000
12-07-2022

Fix request (15u) clean backport to 15u for consistency. No surprises expected. CSR is approved.
12-07-2022

Tests show that SASL DIGEST-MD5 authentication over TLS is also rejected is channel binding is required at the AD end. It seems to apply to any SASL mechanism, not just Kerberos/GSS.
25-01-2022

In addition to Alexey's Fix Request for 11u comment, please note that a CSR was required but has been approved here: https://bugs.openjdk.java.net/browse/JDK-8262258. Also, Alexey started a review thread (https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2021-February/005104.html) but this does not look strictly necessary to me as the patch applies cleanly. I second that no regressions are observed in the relevant test category (com/sun/jndi/ldap). We need this enhancement approved for 11u as there are users affected by compatibility issues with some configurations of Active Directory.
26-02-2021

To allow third party Sasl clients to implement channel binding support it would be ideal if the internal property change (see JDK-8260429) was also backported to 11 and 13.
24-02-2021

Fix request (11u) The original patch applies cleanly.
24-02-2021

One additional note. We have some native GSS code for Windows and Linux. I've recently updated this to support channel bindings. The code is loaded by our framework depending on platform so we need a custom SaslClient implementation. This to read the value of the "internal" jdk.internal.sasl.tlschannelbinding property to get the channel binding data. Would be nicer if the property jdk.internal.sasl.tlschannelbinding was defined as a public constant somewhere so code like this does not need to use an undocumented internal property.
11-01-2021

Context properties at reconnect call are: java.naming.ldap.version=3 com.sun.jndi.ldap.tls.cbtype=tls-server-end-point java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory javax.security.sasl.credentials=[GSSCredential: xxxxxxx 1.2.840.113554.1.2.2 Initiate [class sun.security.jgss.krb5.Krb5InitCredential]] java.naming.provider.url=ldap:/xxxxxxxl/ javax.security.sasl.server.authentication=true java.naming.security.authentication=GSSAPI}
05-01-2021

Been testing this change with build 30. Works fine if used with LDAPS connections. Doesn't seem to work if StartTLS extension is used. Get: Caused by: javax.naming.AuthenticationException: [LDAP: error code 49 - 80090346: LdapErr: DSID-0C090597, comment: AcceptSecurityContext error, data 80090346, v4563] at java.naming/com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3259) at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3205) at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2991) at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2905) at java.naming/com.sun.jndi.ldap.LdapCtx.ensureOpen(LdapCtx.java:2797) at java.naming/com.sun.jndi.ldap.LdapCtx.ensureOpen(LdapCtx.java:2770) at java.naming/com.sun.jndi.ldap.LdapCtx.reconnect(LdapCtx.java:2699) at java.naming/javax.naming.ldap.InitialLdapContext.reconnect(InitialLdapContext.java:193) at rde.util.ldap.LDAPServer.doOpen(LDAPServer.java:410)
05-01-2021

Also, it is a bit odd that javax.naming.Context.SECURITY_AUTHENTICATION [1] does not specify SASL mechanisms like "GSSAPI" as permitted values [2]. I was wondering if we should clarify that. [1] https://docs.oracle.com/en/java/javase/15/docs/api/java.naming/javax/naming/Context.html#SECURITY_AUTHENTICATION [2] https://docs.oracle.com/javase/jndi/tutorial/ldap/security/sasl.html
22-12-2020

[~abakhtin], this still needs a release note - are you planning to write one? Thanks.
22-12-2020

Fix request (13u) Original patch applies cleanly
18-11-2020

Same for jdk8u-fix-request. Please add a proper "Fix Request" comment explaining the details before you seek approval.
01-10-2020

Removing jdk11u-fix-request label as I can see no comment or anything
28-09-2020

Changeset: cfa3f749 Author: Alexey Bakhtin <abakhtin@openjdk.org> Date: 2020-09-25 07:26:54 +0000 URL: https://git.openjdk.java.net/jdk/commit/cfa3f749
25-09-2020

Initial discussion of this issue can be found at https://mail.openjdk.java.net/pipermail/security-dev/2019-December/021052.html https://mail.openjdk.java.net/pipermail/security-dev/2020-January/021140.html https://mail.openjdk.java.net/pipermail/security-dev/2020-February/021278.html https://mail.openjdk.java.net/pipermail/security-dev/2020-May/021864.html
21-05-2020