Question

I'm working on a project where we use JAAS/Krb5LoginModule with useTicketCache & doNotPrompt as well as the allowtgtsessionkey registry change to piggy back our authentication on the windows logon of the domain joined computer.

We then use jgss/kerberos to get a GSS API Kerberos Token (rfc1964) which we use to secure a SOAP Message using the WSS Kerberos Token Profile 1.1.1 when communicating with a service. This involves including the b64 encoded GSS Token in the Security element of the SOAP Envelope/Header and using the client/service sessionKey to sign a component of the element.

We are getting the client/sessionKey by querying the private credentials of the javax.security.auth.Subject which the JAAS/Krb5LoginModule returns and looking for a javax.security.auth.kerberos.KerberosTicket which matches our service peer name and invoking its getSessionKey().

All of this works fine in Java-6, however Java-7 clients are failing as there seems to have been a change in the Kerberos KRB_AP_REQ message that Java-7 creates. The Java-7 KRB_AP_REQ Authenticator contains a sub-key which is different to the sessionKey. Since the Kerberos specification (see excerpt below) says that this subkey supersedes the sessionKey then our Java-6 behaviour of using the sessionKey for signing is no longer correct.

RFC1510 - The Kerberos Network Authentication Service (V5)

5.3.2. Authenticators

subkey  This field contains the client's choice for an encryption
        key which is to be used to protect this specific
        application session. Unless an application specifies
        otherwise, if this field is left out the session key from
        the ticket will be used.

I've not seen anywhere where this change is documented but have confirmed the behaviour at least in Java(TM) SE Runtime Environment (build 1.7.0_11-b21).

At this point unless I have missed something glaringly obvious (and I hope I have), our options seem to be:

  1. Change the Java-7 Kerberos Configuration to revert to Java-6 behaviour - unfortunately I've not seen anything in the docs that seems to suggest that this is possible.

  2. Find a way to get access to the subkey. For this options I have explored are

    a. Decode the b64 encoded GSS Token, pull out the encrypted Authenticator, decrypt it using the sessionKey, decode the ASN.1 DER encoding and pull out the subkey.

    b. Use what appears to be non-standard GSS API Extensions and use the ExtendedGSSContext.inquireSecContext() method with KRB5_GET_SESSION_KEY to get at the subKey.

Any suggestions/insight in to these or other possible options?

Was it helpful?

Solution

We also experience this issue when using JGSS Api in Java 1.7 to obtain the client's session key. Apparently, in Java 1.6 the sub-key was always cloned from the session key, see the sun.security.krb5.EncryptionKey constructor:

EncryptionKey(EncryptionKey encryptionkey)
    throws KrbCryptoException
{
    keyValue = (byte[])(byte[])encryptionkey.keyValue.clone();
    keyType = encryptionkey.keyType;
}

Starting from Java 1.7.0_b07, this constructor utilizes java.security.SecureRandom to generate a new subkey. I think this has been done as part of JDK-4460771 : Kerberos should be able to generate sub-session keys. It seems that the com.sun.security.jgss.ExtendedGSSContext provides the "standard" way to access the subkey from now on (on Sun JVMs), so I guess we should use this class if it is available (on the underlying JVM), see:

JDK-6710360 : export Kerberos session key to applications

Thanks, Detelin

OTHER TIPS

I don't see anything in the ExtendedGSSContext.inquireSecContext() doc to indicate that it returns the subkey if present for KRB5_GET_SESSION_KEY; do you know from some other source that it does?

In any case, using the subkey is what you need to do. I would look at it this way: your original implementation was not correct, because the WSS Kerberos doc clearly states that the subkey is to be used if present. It just happened to work because the Java 6 Kerberos library did not generate a subkey. Now that one has appeared your bug is revealed, and you have to fix it.

I'm not familiar with WSS, but the doc seems to indicate that you can choose various encodings for the token, and one is to use GSSAPI instead of a Kerberos AP-REQ directly. Perhaps if you had used GSSAPI to begin with, it would have insulated you from this change -- and perhaps switching to it now would be the easiest fix.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top