GSS-API and libkrb5 behavior for Anonymous tickets

Nicolas Williams Nicolas.Williams at
Tue Nov 3 12:41:55 EST 2009

In my interpretation, the principles of the GSS-API w.r.t. anonymity are
as follows:

 - If you use a non-default credential handle when calling
   gss_init_sec_context(), then the mechanism is constrained to
   authenticating only that handle's desired_name as the initiator
   principal, UNLESS the anon req_flag is set (more on that below).

    - If you use a credential handle for a desired_name with anonymous
      or anonymous-like name type, then you can only get anonymity (or
      pseudonymity; see below) when you call gss_init_sec_context() with
      that credential handle.

      The GSS-API doesn't have a notion of credential store or of
      "initial credentials", so it's possible that one could get
      pseudonymity instead of anonymity unless the caller sets the
      anonymous req_flag (they have to then check that it's set in the
      ret_flags).  That is, the implementation might fetch an anonymous
      TGT and then fetch service tickets using that TGT, which might
      allow all the various services to track the initiators' actions
      back to that one anon TGT.  gss_acquire_cred() could store
      credentials for anonymous desired_names in the current ccache, but
      I'd rather that it always return fresh credentials when
      desired_name is an anonymous name.

 - To use a default credential handle is the same as to use a credential
   handle whose desired_name matches the default principal of the
   current credential store (ccache).  See above.

 - req_flags are all optional; a mechanism is free to grant more or
   fewer than requested, and the caller of gss_init_sec_context() must
   check ret_flags.  However, ret_flags must be set appropriately as
   soon as possible!  RFC2743 says:

   Callers wishing to perform context establishment only if anonymity
   support is provided should transfer a returned token from
   GSS_Init_sec_context() to the peer only if it is accompanied by a
   TRUE anon_state indicator.

   This leaves the mechanism designer/implementor a lot of freedom.  Too
   much freedom, I think.  But not so much freedom that a careful
   application would ever authenticate a non-anon initiator

   (Aside: it would be very odd to set the anonymous ret_flag when the
   caller did not request it and the initiator credential handle was not
   an anonymous one.  This should just not happen.  Note that mechanisms
   that can only do anon initiator name authentication can only have
   anon cred handles.  If you use SPNEGO, a default credential handle,
   and such a mechanism, then you could see the anon ret_flag set even
   though the caller did not set the anon req_flag.)

   Thus to call gss_init_sec_context() with the default credential when
   there's a non-anonymous crendential available, and the anonymous
   req_flag means that the mechanism is free to authenticate the
   initiator non-anonymously (and not set the anonymous ret_flag).

   Just because the mechanism can do that doesn't mean it should.  I'd
   rather treat the anon req_flag as critical in the mechanism
   implementations, even though from the application's p.o.v. it's

We can derive these rules for the krb5 mech from the above:

1) If the app calls gss_import_name() with GSS_C_NT_ANONYMOUS to get an
   anon name, then calls gss_acquire_cred(), then for the krb5 mech that
   implements anonymous PKINIT this should work.

   We may need to define a krb5-specific anon name-type whose syntax
   allows the specification of a realm name.  But use of that should be

2) If the app calls gss_acquire_cred() with desired_name == some
   anonymous or anonymous-like name, then the krb5 mech should acquire
   anon tickets, or defer this to the point where gss_init_sec_context()
   is called.

3) If the app calls gss_init_sec_context() with an anonymous credential
   handle then:

   a) the krb5 mech should authenticate that credential's anonymous
   desired_name and NEVER authenticate the caller's default credential's
   desired_name, if there are any non-anon default creds;

   b) the anon ret_flag should be set regardless of whether the anon
   req_flag was set.

4) If the app calls gss_init_sec_context() with a default credential, or
   with a non-anonymous credential handle *and* sets the anon req_flag,
   then technically the krb5 mech should attempt anonymous
   authentication and may fail without authenticating the non-anon
   initiator name if it could not do anonymous authentication.  Ideally
   the mechanism should attempt anon auth and must fail without
   authenticating the non-anon initiator.  (If anon auth succeeds, then
   the anon ret_flag must be set, of course.)


More information about the krbdev mailing list