A fundamental JGSS-API bug?

Weijun Wang weijun.wang at oracle.com
Fri Jun 7 06:42:45 PDT 2013


Hi All

The GSSContext::initSecContext() method could either return a token 
(possibly null if no more token is needed) when the call succeeds or 
throw a GSSException if there is a failure, but not *both*. The same 
applies to acceptSecContext().

However, according to RFC 2743 2.2.1 [1], the C bindings of GSS-API:

    It is the caller's responsibility to establish a communications path
    to the target, and to transmit any returned output_token (independent
    of the accompanying returned major_status value) to the target over
    that path.

In fact, MIT krb5's gss-client.c sample does show:

         do {
             maj_stat = gss_init_sec_context(..., &send_tok, ...);
             ...
             if (send_tok.length != 0) {    # send the token anyway
                 if (send_token(..., &send_tok) < 0) {
                     ...
                     return -1;
                 }
             }                              # before return value check
             if (maj_stat != GSS_S_COMPLETE
                 && maj_stat != GSS_S_CONTINUE_NEEDED) {
                 ...
                 return -1;
             }

             if (maj_stat == GSS_S_CONTINUE_NEEDED) {
                 ...
             }
         } while (maj_stat == GSS_S_CONTINUE_NEEDED);

Without the ability to send a token when there is a failure, a Java 
program has no chance to tell the other side what's happening. This is 
very user-unfriendly. Also, in the case of SPNEGO, a "reject" 
NegTokenResp token will never be able to sent.

I cannot find a good way to fix it without changing the semantic of 
current APIs. Maybe we can add a new GSSException::getResidue() method 
to return this last token. But that means the method call will be quite 
complicated, something like

         try {
             send(initSecContext(inToken));
         } catch (GSSException e) {
             if (e.getResidue() != null) {
                 send(e.getResidue());
             }
             throw e;
         }

As for the overloaded initSecContext(InputStream, OutputStream) style, 
it looks easier to update this method to do the correct thing without 
any new API. However, the change will be very confusing because there is 
no more number of written bytes to return. More importantly, if it's 
just a silent behavior change, we'll have to care about compatibility 
(Maybe someone already added his/her own KRB-ERROR sending codes?), 
which makes the situation much tougher.

Thanks
Max

[1] http://tools.ietf.org/html/rfc2743#page-46


More information about the security-dev mailing list