[krbdev.mit.edu #8845] SPNEGO init/accept output parameter bugs

"Greg Hudson via RT" <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.bugs
Message-ID <[email protected]>
Tue Nov 05 13:47:37 2019: Request 8845 was acted upon.
 Transaction: Ticket created by [email protected]
       Queue: krb5
     Subject: SPNEGO init/accept output parameter bugs
       Owner: Nobody
  Requestors: [email protected]
      Status: open
 Ticket <URL: https://krbdev.mit.edu/rt/Ticket/Display.html?id=8845 >


gss_init_sec_context() and gss_accept_sec_context() both output a token and
either create or modify a security context. There are some additional outputs:
actual_mech_type, ret_flags, and time_rec for gss_init_sec_context(), and
src_name, mech_type, ret_flags, time_rec, and delegated_cred_handle for
gss_accept_sec_context(). RFC 2744 sections 5.1 and 5.19 define some rules for
how these parameters should be set when GSS_S_CONTINUE_NEEDED is returned.

Although the mechglue initializes most output parameters, it does not do so for
ret_flags and time_rec. This is a separate bug, which impacts the following
SPNEGO misbehaviors; if SPNEGO does not set these output parameters, the
caller's value will remain unchanged.

The current SPNEGO implementation has the following bugs related to the
additional output parameters:

* gss_init_sec_context() only sets ret_flags if the underlying mech is called
and returns GSS_S_COMPLETE, or if SPNEGO itself will return GSS_S_COMPLETE.
gss_accept_sec_context() initializes ret_flags to 0, and only sets ret_flags to
another value if the underlying mech is called and returns GSS_S_COMPLETE;
ret_flags could remain as 0 on SPNEGO's final return from
gss_accept_sec_context(), if the MIC exchange forces an extra round trip.

* gss_init_sec_context() and gss_accept_sec_context() do not filter out
PROT_READY from ret_flags as required by RFC 4178.

* gss_init_sec_context() and gss_accept_sec_context() pass time_rec directly to
the underlying mech. gss_accept_sec_context() initializes time_rec to 0 but
gss_init_sec_context() does not. Neither function will set time_rec to a
meaningful value if the underlying mech is not called on the final SPNEGO call
due to the MIC exchange. Note that time_rec is relative to the current time; if
SPNEGO records time_rec from the underlying mech at one step and reports it to
the caller at a later step, the time differential between steps could render
that value inaccurate. SPNEGO could either adjust the value by the
differential, or call gss_context_time() on the underlying context.

* gss_accept_sec_context() initializes mech_type to GSS_C_NO_OID and passes it
directly to the underlying mech. If the underlying mech is not called on the
final step, mech_type will remain as GSS_C_NO_OID.

* gss_accept_sec_context() initializes delegated_cred_handle to
GSS_C_NO_CREDENTIAL and passes it directly to the underlying mech. SPNEGO could
report a delegated cred to the caller too early (before the MIC exchange) and
not on the final call.

* gss_accept_sec_context() could leak a value of src_name (recorded as
sc->internal_name) if the underlying mech reports it twice. RFC 2744 doesn't
explicitly prohibit this, although it seems like it should be unusual.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.