JDK-8078439 : SPNEGO auth fails if client proposes MS krb5 OID
  • Type: Bug
  • Component: security-libs
  • Sub-Component: org.ietf.jgss
  • Affected Version: 8u40,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2015-04-22
  • Updated: 2016-08-24
  • Resolved: 2015-05-05
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 8 JDK 9 Other
8u51Fixed 9 b64Fixed openjdk7uFixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
openjdk version "1.8.0_40-"
OpenJDK Runtime Environment (build 1.8.0_40--vagrant_2015_03_13_10_36-b25)
OpenJDK 64-Bit Server VM (build 25.40-b25, mixed mode)

Ubuntu 10.04 64-bit

I believe I've found a bug in OpenJDK 1.8.0_40, introduced in commit d777e2918a77: http://hg.openjdk.java.net/jdk8u/jdk8u40/jdk/file/d777e2918a77/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java

The change introduced on line 548 means that an authentication mechanism is only accepted if the OID of the mechanism desired is the first in the list of mechanisms specified as acceptable in the incoming ticket.

In the case of my current client their service tickets are specifying 4 acceptable mechanism OIDs, but the only available mechanism's OID appears second on that list. So whilst the server can satisfy the ticket, the code change on line 548 prevents this from happening.

Using the same server code, the same Kerberos KDC, and OpenJDK 1.8.0_31, everything works. Changing only the JDK results in the mechContext not being properly populated, which in turn causes a NullPointerException from some Spring Security Kerberos code.

REGRESSION.  Last worked in version 8u31

Provide a Kerberos ticket where the mechanism OID that is supported by the server is _not_ the first listed in the ticket.

The list of acceptable mechanism OIDs in our ticket was: 1.2.840.48018.1.2.2, 1.2.840.113554.1.2.2,,

Our server supported 1.2.840.113554.1.2.2.

The following code then throws a NullPointer on context.getSrcName(), as the context has not been created.
GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null);
byte[] responseToken = context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length);
String user = context.getSrcName().toString();

Executing the following line...

context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length);

... should result in context's mechCtxt being set to a SpNegoContext instance. This in turn has a member mechContext that should be a GSSContextImpl wrapping a Krb5Context.
SpNegoContext's mechContext member was never populated.

This bug can be reproduced always.

Based on 8u-dev nighlty results UR SQE OK to take the regression bug fix to CPU15_03

Has been this fix pushed to 8u-CPU WS?

CPU15_03-critical-request justification: This is a regression introduced by JDK-8048194 in 8u40 and 8u45. When a browser (or any other Windows native client) is visiting a Java server program protected by SPNEGO, it will always fail. Multiple incident reports have been reported on this issue. Fixes have been pushed to jdk9/dev and jdk8u/jdk8u-dev. The fix is specifically coded for this exact case (when client presents a non-standard Kerberos object identifier, accept it) and has no affect otherwise. Therefore it should be safe to be included in a CPU release.

P2 now. Impact: H, authentication failure. Likelihood: M, a browser (IE, Firefox, Chrome all affected) as a SPNEGO client is quite common on Windows. Workaround: H, update the server side codes (read the comment of Apr 25). Reporter of this bug has tried it and it works for them. However, since the codes are most likely in a framework, app developers and end users will not be easy to change it.

Client is proposing 2 OIDs, [1.2.840.48018.1.2.2, 1.2.840.113554.1.2.2], 1st one being Microsoft's own krb5 OID and 2nd the standard one. Java only understands the 2nd one but before JDK-8048194 it blindly accepted the mechToken without looking at the OID. Since it's also krb5, the mechToken is processed correctly and everything goes on. After JDK-8048194, Java does not recognize the OID anymore and asks the client to send another mechToken with 1.2.840.113554.1.2.2. I believe a lot of people is using the Microsoft OID. I will see if it's possible to recognize both OIDs. On the other hand, the app code has context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length); String user = context.getSrcName().toString(); which is not standard. The acceptSecContext call should be in a loop until a context is established, and then it can call getSrcName(). Hopefully after the client sees the server request for a 1.2.840.113554.1.2.2 mechToken it can send one and the server can go on. There is a workaround (in app code) to tweak the incoming packet to put 1.2.840.113554.1.2.2 as the 1st OID so Java accepts it again: In my experiment, the first 48 bytes of the incoming SPNEGO packet look like this: 0000: 60 82 02 2D 06 06 2B 06 01 05 05 02 A0 82 02 21 0010: 30 82 02 1D A0 18 30 16 06 09 2A 86 48 82 F7 12 0020: 01 02 02 06 09 2A 86 48 86 F7 12 01 02 02 A1 04 Here, the OIDs are the 11 bytes from 0x18 and 0x23 starting with 06 09. The only difference between the 2 OIDs are 82 (at 0x1D) and 86 (at 0x28). If you swap them, Java will happily accept it. This is only a workaround and the real fix should be inside JDK. If the packet is bigger the 2nd byte might be 83 and you need to look a bit further for the OIDs (still starting with 06 09).

OpenJDK mail thread at : http://mail.openjdk.java.net/pipermail/jdk8u-dev/2015-April/003444.html