JDK-8237647 : LoginException: Message stream modified (41) for uppercase username with krb5
  • Type: Bug
  • Component: security-libs
  • Sub-Component: org.ietf.jgss:krb5
  • Affected Version: 11.0.6
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2020-01-22
  • Updated: 2021-07-02
  • Resolved: 2021-07-02
Related Reports
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
Red Hat Enterprise Linux 7 Version 7.7

Exception with:
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.6+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.6+10, mixed mode)

Works with:
openjdk version "11.0.5" 2019-10-15
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.5+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.5+10, mixed mode)

A DESCRIPTION OF THE PROBLEM :
When the username is entered in uppercase, krb5 throws an exception authentication again active directory with OpenJDK 11.0.6+10. Trying it with OpenJDK 11.0.5+10, it works.

Enter the username in lowercase, it works either way

REGRESSION : Last worked in version 11

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Trying to authenticate with krb5 again active directory with uppercase username and password

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
[mseele@bbl2xap1 michael]$ /tmp/jdk/jdk-11.0.5+10/bin/java -Dsun.security.krb5.debug=true -jar adTest.jar jaas.conf krb5.conf
Username:
DEP04801
Password:

Java config name: /nfs/bbitsrv1/public/mseele/guhSync/michael/krb5.conf
Loading krb5 profile at /nfs/bbitsrv1/public/mseele/guhSync/michael/krb5.conf
Loaded from Java config
>>> KdcAccessibility: reset
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 20 19 16 23.
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=depbblhps1dc001.bbl.ms.philips.com UDP:88, timeout=30000, number of retries =3, #bytes=172
>>> KDCCommunication: kdc=depbblhps1dc001.bbl.ms.philips.com UDP:88, timeout=30000,Attempt =1, #bytes=172
>>> KrbKdcReq send: #bytes read=220
>>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 18, salt = CODE1.EMI.PHILIPS.COMMichael.Seele, s2kparams = null
         PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

>>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
         PA-DATA type = 16

>>>Pre-Authentication Data:
         PA-DATA type = 15

>>> KdcAccessibility: remove depbblhps1dc001.bbl.ms.philips.com
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
         sTime is Wed Jan 22 11:03:04 CET 2020 1579687384000
         suSec is 470232
         error code is 25
         error Message is Additional pre-authentication required
         sname is krbtgt/CODE1.EMI.PHILIPS.COM@CODE1.EMI.PHILIPS.COM
         eData provided.
         msgType is 30
>>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 18, salt = CODE1.EMI.PHILIPS.COMMichael.Seele, s2kparams = null
         PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

>>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
         PA-DATA type = 16

>>>Pre-Authentication Data:
         PA-DATA type = 15

KrbAsReqBuilder: PREAUTH FAILED/REQ, re-send AS-REQ
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 20 19 16 23.
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 20 19 16 23.
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=depbblhps1dc001.bbl.ms.philips.com UDP:88, timeout=30000, number of retries =3, #bytes=253
>>> KDCCommunication: kdc=depbblhps1dc001.bbl.ms.philips.com UDP:88, timeout=30000,Attempt =1, #bytes=253
>>> KrbKdcReq send: #bytes read=114
>>> KrbKdcReq send: kdc=depbblhps1dc001.bbl.ms.philips.com TCP:88, timeout=30000, number of retries =3, #bytes=253
>>> KDCCommunication: kdc=depbblhps1dc001.bbl.ms.philips.com TCP:88, timeout=30000,Attempt =1, #bytes=253
>>>DEBUG: TCPClient reading 2888 bytes
>>> KrbKdcReq send: #bytes read=2888
>>> KdcAccessibility: remove depbblhps1dc001.bbl.ms.philips.com
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
>>> KrbAsRep cons in KrbAsReq.getReply DEP04801
Authentication successfull
ACTUAL -
[mseele@bbl2xap1 michael]$ /tmp/jdk/jdk-11.0.6+10/bin/java -Dsun.security.krb5.debug=true -jar adTestRep.jar jaas.conf krb5.conf
Username:
DEP04801
Password:

Java config name: /nfs/bbitsrv1/public/mseele/guhSync/michael/krb5.conf
Loading krb5 profile at /nfs/bbitsrv1/public/mseele/guhSync/michael/krb5.conf
Loaded from Java config
>>> KdcAccessibility: reset
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 20 19 16 23.
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=depbblhps1dc001.bbl.ms.philips.com UDP:88, timeout=30000, number of retries =3, #bytes=188
>>> KDCCommunication: kdc=depbblhps1dc001.bbl.ms.philips.com UDP:88, timeout=30000,Attempt =1, #bytes=188
>>> KrbKdcReq send: #bytes read=220
>>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 18, salt = CODE1.EMI.PHILIPS.COMMichael.Seele, s2kparams = null
         PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

>>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
         PA-DATA type = 16

>>>Pre-Authentication Data:
         PA-DATA type = 15

>>> KdcAccessibility: remove depbblhps1dc001.bbl.ms.philips.com
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
         sTime is Wed Jan 22 11:01:37 CET 2020 1579687297000
         suSec is 578081
         error code is 25
         error Message is Additional pre-authentication required
         sname is krbtgt/CODE1.EMI.PHILIPS.COM@CODE1.EMI.PHILIPS.COM
         eData provided.
         msgType is 30
>>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 18, salt = CODE1.EMI.PHILIPS.COMMichael.Seele, s2kparams = null
         PA-ETYPE-INFO2 etype = 23, salt = null, s2kparams = null

>>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
         PA-DATA type = 16

>>>Pre-Authentication Data:
         PA-DATA type = 15

KrbAsReqBuilder: PREAUTH FAILED/REQ, re-send AS-REQ
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 20 19 16 23.
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 20 19 16 23.
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=depbblhps1dc001.bbl.ms.philips.com UDP:88, timeout=30000, number of retries =3, #bytes=268
>>> KDCCommunication: kdc=depbblhps1dc001.bbl.ms.philips.com UDP:88, timeout=30000,Attempt =1, #bytes=268
>>> KrbKdcReq send: #bytes read=114
>>> KrbKdcReq send: kdc=depbblhps1dc001.bbl.ms.philips.com TCP:88, timeout=30000, number of retries =3, #bytes=268
>>> KDCCommunication: kdc=depbblhps1dc001.bbl.ms.philips.com TCP:88, timeout=30000,Attempt =1, #bytes=268
>>>DEBUG: TCPClient reading 2910 bytes
>>> KrbKdcReq send: #bytes read=2910
>>> KdcAccessibility: remove depbblhps1dc001.bbl.ms.philips.com
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
Exception in thread "main" javax.security.auth.login.LoginException: Message stream modified (41)
        at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:782)
        at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:592)
        at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:726)
        at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:665)
        at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:663)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:663)
        at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:574)
        at de.guhsoft.ad.Test.main(Test.java:29)
Caused by: KrbException: Message stream modified (41)
        at java.security.jgss/sun.security.krb5.KrbKdcRep.check(KrbKdcRep.java:53)
        at java.security.jgss/sun.security.krb5.KrbAsRep.decrypt(KrbAsRep.java:159)
        at java.security.jgss/sun.security.krb5.KrbAsRep.decryptUsingPassword(KrbAsRep.java:139)
        at java.security.jgss/sun.security.krb5.KrbAsReqBuilder.resolve(KrbAsReqBuilder.java:310)
        at java.security.jgss/sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:447)
        at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:744)
        ... 8 more


---------- BEGIN SOURCE ----------
------------------------------------------------------------------------------
--------------------------------- Test Code ---------------------------------
------------------------------------------------------------------------------
package de.guhsoft.ad;

import java.io.File;
import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

public class Test {

	public static void main(String[] args) throws LoginException {
		if (System.getProperty("java.security.auth.login.config") == null) { //$NON-NLS-1$
			System.setProperty("java.security.auth.login.config", new File(args[0]).getAbsolutePath()); //$NON-NLS-1$
		}
		if (System.getProperty("java.security.krb5.conf") == null) { //$NON-NLS-1$
			System.setProperty("java.security.krb5.conf", new File(args[1]).getAbsolutePath()); //$NON-NLS-1$
		}
		System.out.println("Username:"); //$NON-NLS-1$
		String login = System.console().readLine();
		System.out.println("Password:"); //$NON-NLS-1$
		char[] password = System.console().readPassword();
		
		final LoginContext loginContext = new LoginContext("AuthenticationService", new LoginAndPasswordCallbackHandler(login, new String(password))); //$NON-NLS-1$
		loginContext.login();
		loginContext.logout();
		System.out.println("Authentication successfull"); //$NON-NLS-1$
	}

	private static class LoginAndPasswordCallbackHandler implements CallbackHandler {

		private String fLogin;

		private String fPassword;

		/**
		 * The standard constructor of the class.
		 * 
		 * @param login
		 *            The login ...
		 * @param password
		 *            ... and password which shall be authenticated.
		 */
		public LoginAndPasswordCallbackHandler(final String login, final String password) {
			super();
			this.fLogin = login;
			this.fPassword = password;
		}

		@Override
		public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
			for (int i = 0; i < callbacks.length; i++) {
				if (callbacks[i] instanceof NameCallback) {
					final NameCallback nameCallback = (NameCallback) callbacks[i];
					nameCallback.setName(this.fLogin);
				} else if (callbacks[i] instanceof PasswordCallback) {
					final PasswordCallback passwordCallback = (PasswordCallback) callbacks[i];
					final String password = this.fPassword;
					char[] passwordAsCharArray = new char[password.length()];
					password.getChars(0, password.length(), passwordAsCharArray, 0);
					passwordCallback.setPassword(passwordAsCharArray);
				} else {
					throw new UnsupportedCallbackException(callbacks[i]);
				}
			}
		}
	}

}
------------------------------------------------------------------------------
--------------------------------- Test Code ---------------------------------
------------------------------------------------------------------------------

-----------------------------------------------------------------------------
--------------------------------- jaas.conf ---------------------------------
-----------------------------------------------------------------------------
AuthenticationService {
  com.sun.security.auth.module.Krb5LoginModule required;
};
-----------------------------------------------------------------------------
--------------------------------- jaas.conf ---------------------------------
-----------------------------------------------------------------------------

-----------------------------------------------------------------------------
--------------------------------- krb5.conf --------------------------------
-----------------------------------------------------------------------------
[libdefaults]
    default_realm = <SERVER_NAME>
    default_checksum = rsa-md5

[realms]
    <SERVER_NAME> = {
        kdc = <SERVER_NAME>
    }

[domain_realms]
    <SERVER_NAME> = <SERVER_NAME>
-----------------------------------------------------------------------------
--------------------------------- krb5.conf --------------------------------
-----------------------------------------------------------------------------

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

CUSTOMER SUBMITTED WORKAROUND :
Only workaround is to login with lowercase username

FREQUENCY : always



Comments
Further response from the submitter: It's not a bug, it is related to https://bugs.openjdk.java.net/browse/JDK-8215032 OpenJDK Implementation: > https://github.com/AdoptOpenJDK/openjdk-jdk11u/commit/37ad8d8b82b6199fa254e941243cc722cc2a35fb Got it fixed by adding -Dsun.security.krb5.disableReferrals=true
23-01-2020

As per submitter this is a regression introduced in OpenJDk 11.0.6+10 as it works fine with 11.0.5_10. The verification test requires Active Directory setup.
22-01-2020

Requested more information to reproduce the problem.
22-01-2020