Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7065337

GSSException when using AES-128 encryption for LDAP connection to AD

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 6
    • security-libs

      FULL PRODUCT VERSION :
      java version "1.7.0"
      Java(TM) SE Runtime Environment (build 1.7.0-b147)
      Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)

      and

      java version "1.6.0_22"
      Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
      Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Client:
      - Microsoft Windows XP [Version 5.1.2600]
      - Microsoft Windows [Version 6.1.7600]

      ActiveDirectory Server:
      - Microsoft Windows [Version 6.0.6001]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Kerberos configuration (krb5.ini)

      [libdefaults]
         default_realm = SSO.TEST.DE
         dns_lookup_kdc = true
         default_tgs_enctypes = aes256-cts aes128-cts des3-cbc-sha1 des-cbc-md5 des-cbc-crc
         dns_lookup_realm = true

      [realms]
        SSO.TEST.DE = {
      default_domain = SSO.TEST.DE
      kdc = WIN-6HYO3DBXS04:88
      }

      [domain_realm]
          sso.test.de = SSO.TEST.DE
          .sso.test.de = SSO.TEST.DE

      [login]
              krb4_convert = false
              krb4_get_tickets = false


      A DESCRIPTION OF THE PROBLEM :
      If I try to establish an AES-128 encrypted LDAP connection to an Microsoft Active Directory I always get an GSSException, if a none AES encryption is used, the connection could be established successful.




      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      - Set the default encryption types for kerberos to default_tgs_enctypes = aes256-cts aes128-cts des3-cbc-sha1 des-cbc-md5 des-cbc-crc

      - Get an Kerberos Ticket by using JAAS to login to the domain
      - Use the Ticket to establish a connection to the LDAP server

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      A connection to the LDAP-Server is established and ready to use, the LDAP communication is encrypted.
      ACTUAL -
      No connection is established, only an Exception is thrown

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Security Providers -
      SUN version 1.6
      SunRsaSign version 1.5
      SunJSSE version 1.6
      SunJCE version 1.6
      SunJGSS version 1.0
      SunSASL version 1.5
      XMLDSig version 1.0
      SunPCSC version 1.6
      SunMSCAPI version 1.6
      Debug is true storeKey false useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is null tryFirstPass is false useFirstPass is false storePass is false clearPass is false
      [Krb5LoginModule] user entered username: ids

      Acquire TGT using AS Exchange
      principal is ###@###.###
      EncryptionKey: keyType=3 keyBytes (hex dump)=0000: 68 1F D9 37 EF 49 2C 16
      EncryptionKey: keyType=1 keyBytes (hex dump)=0000: 68 1F D9 37 EF 49 2C 16
      EncryptionKey: keyType=23 keyBytes (hex dump)=0000: 46 0F 3C 18 6B CE 1E 04 70 92 01 AE 0C 59 E4 1F F.<.k...p....Y..

      EncryptionKey: keyType=16 keyBytes (hex dump)=0000: F7 94 F8 86 E9 B0 5D 76 73 4F 0E 31 D5 80 2A 79 ......]vsO.1..*y
      0010: 94 6D 46 10 F2 A1 A4 01
      EncryptionKey: keyType=17 keyBytes (hex dump)=0000: 7F F4 0E B2 7C EB FF F7 E4 CC DE 21 1F 92 44 EF ...........!..D.

      EncryptionKey: keyType=18 keyBytes (hex dump)=0000: 17 B7 FE B7 31 80 5C 04 77 77 FA 20 6C 2C A2 1B ....1.\.ww. l,..
      0010: 8C 6B 3F 76 10 A0 0B 5E 83 DA 48 3E 20 FC 04 06 .k?v...^..H> ...

        Commit Succeeded

      No encryption was performed by peer.
      javax.naming.AuthenticationException: GSSAPI [Root exception is javax.security.sasl.SaslException: Final handshake failed [Caused by GSSException: Token had invalid integrity check (Mechanism level: Corrupt checksum in Wrap token)]]
      at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(Unknown Source)
      at com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
      at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
      at com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
      at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
      at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
      at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
      at javax.naming.InitialContext.init(Unknown Source)
      at javax.naming.InitialContext.<init>(Unknown Source)
      at javax.naming.directory.InitialDirContext.<init>(Unknown Source)
      at vsjtest.JRETalkToServerAction.run(JREClient.java:60)
      at java.security.AccessController.doPrivileged(Native Method)
      at javax.security.auth.Subject.doAs(Unknown Source)
      at vsjtest.JREClient.performLogin(JREClient.java:100)
      at vsjtest.JREClient.main(JREClient.java:120)
      Caused by: javax.security.sasl.SaslException: Final handshake failed [Caused by GSSException: Token had invalid integrity check (Mechanism level: Corrupt checksum in Wrap token)]
      at com.sun.security.sasl.gsskerb.GssKrb5Client.doFinalHandshake(Unknown Source)
      at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source)
      ... 18 more
      Caused by: GSSException: Token had invalid integrity check (Mechanism level: Corrupt checksum in Wrap token)
      at sun.security.jgss.krb5.WrapToken_v2.getDataFromBuffer(Unknown Source)
      at sun.security.jgss.krb5.WrapToken_v2.getData(Unknown Source)
      at sun.security.jgss.krb5.WrapToken_v2.getData(Unknown Source)
      at sun.security.jgss.krb5.Krb5Context.unwrap(Unknown Source)
      at sun.security.jgss.GSSContextImpl.unwrap(Unknown Source)
      ... 20 more


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      UsernamePasswordHandler.java
      /**
       * An implemeentation of the JAAS CallbackHandler interface that handles
       * NameCallbacks and PasswordCallbac
       */
      public class UsernamePasswordHandler implements CallbackHandler {

        private String username;
        private char[] password;

        public UsernamePasswordHandler(String username, char[] password) {
          this.username = username;
          this.password = password;
        }

        public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
          for (int i = 0; i < callbacks.length; i++) {
            Callback c = callbacks[i];
            if( c instanceof NameCallback ) {
              NameCallback nc = (NameCallback) c;
              nc.setName(username);
            }
            else if( c instanceof PasswordCallback ) {
              PasswordCallback pc = (PasswordCallback) c;
              pc.setPassword(password);
            }
            else {
              throw new UnsupportedCallbackException(c, "Unrecognized Callback");
            }
          }
        }
      }


      JREClient.java:

      /**
       * This class provides most of the credential gathering and processing inside a
       * privileged action environment.
       */
      class JRETalkToServerAction implements PrivilegedExceptionAction {

        private String serverUrl;
        private Subject subject;

        /**
         * Create a TalkToServerAction.
         *
         * @param serverAddress
         * the URL of the server we are contacting.
         * @param subject
         */
        public JRETalkToServerAction(String serverAddress, Subject subject) {
          this.serverUrl = serverAddress;
          this.subject = subject;
        }

        /**
         * This method performs the SPNEGO authenthentication with server whose URL is
         * given. After authentication, the method will get an InputStream for server
         * data.
         *
         * @return the InputStream for the server.
         */
        public Object run() throws GSSException, IOException {

          Hashtable env = new Hashtable();
          env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
          env.put(Context.PROVIDER_URL, serverUrl);
          env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
          env.put("javax.security.sasl.qop", "auth-conf");
          env.put("javax.security.sasl.server.authentication", "true");
          try {
            DirContext ctx = new InitialDirContext(env);

            String[] justOneAttr = { "name" };

            Attributes result = ctx.getAttributes("CN=Users,DC=sso,DC=test,DC=de", justOneAttr);
            System.out.println(result.toString());
            String userName = "CN=thomas,CN=Users,DC=sso,DC=test,DC=de";
            // String newPassword = "##Test!!!1";
            String newPassword = "Service##";
            // Replace the "unicdodePwd" attribute with a new value
            // Password must be both Unicode and a quoted string
            String newQuotedPassword = "\"" + newPassword + "\"";
            byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
            ModificationItem[] mods = new ModificationItem[1];
            mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));

            ctx.modifyAttributes(userName, mods);

          } catch (NamingException e) {
            e.printStackTrace();
          }
          return null;
        }
      }

      public class JREClient {

        static void outputProviders() {
          System.out.println("Security Providers -");
          Provider[] providers = Security.getProviders();
          for (int i = 0; i < providers.length; i++) {
            System.out.println(providers[i]);
          }
        }

        static void performLogin(LoginContext lc, String serverAddress) throws LoginException, PrivilegedActionException, IOException {
          lc.login();
          Subject subject = lc.getSubject();

          // Perform the authentication as the generated subject
          Subject.doAs(subject, new JRETalkToServerAction(serverAddress, subject));

        }

        public static void main(String[] args) throws Exception {
          if (args.length < 3) {
            System.out.println("Usage: java fatclient.UsernamePasswordClient [url] [username] [password]");
            System.exit(0);
          }

          String serverAddress = args[0];
          String username = args[1];
          String password = args[2];

         

          outputProviders();

          LoginContext lc = new LoginContext("JREUsernamePassword", new UsernamePasswordHandler(username, password.toCharArray()));

          performLogin(lc, serverAddress);
        }

      }

      jaas.config:

      /*
       Copyright 2007 Quest Software, Inc.

       ALL RIGHTS RESERVED.

       Permission to use, copy, modify, and distribute this software and its
       documentation is hereby granted for internal and non-commercial use only.

       Quest reserves all other rights. No other use of the software, documentation,
       or modifications thereto is permitted without prior written consent from
       Quest Software, Inc.
       
       This software is being provided "AS IS" without warranty of any kind and without
       any particular purpose. In no event shall Quest Software, Inc be liable for
       damage of any kind arising out of or in connection with the use or performance
       of this software.
       */


      JREUsernamePassword {
       com.sun.security.auth.module.Krb5LoginModule sufficient debug=true;
      };


      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      - Use SSL to get an encrypted LDAP Connection
      - Use the Kerberos Implementation from Vintela

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: