Subject: RE: mastering CONTEXT_EXPIRED

From: "Linn, John" <[email-masked]>
Date: Fri, 7 Nov 1997 11:31:29 -0500

In the attached, I think Martin may be assuming rules stronger than
we've stated, at least explicitly.  We've imposed a requirement on
callers that they're to call delete_sec_context(), thereby enabling
timely flushing of keys and conservation of other resources.  I believe,
though, that we've been silent about whether or not there are other
circumstances than receipt of a delete_sec_context() call under which a
mechanism may flush context records for a context which has passed its
expiration (and for which, therefore, it would subsequently return
GSS_S_NO_CONTEXT if queried with inquire_context() using the late
context's handle). A caller might be understandably surprised, though,
if it were to receive a handle for a newly established context which
appears indistinguishable from a handle previously received and
corresponding to a context subsequently expired and flushed. Can/should
we make any statement on this issue?  What assumptions have mechanism
implementors made in this area?

--jl

> ----------
> From: 	Martin Rex[SMTP:[email-masked]]
> Reply To: 	[email-masked]
> Sent: 	Thursday, November 06, 1997 12:48 PM
> To: 	[email-masked]
> Cc: 	[email-masked]
> Subject: 	Re: mastering CONTEXT_EXPIRED
> 
> Linn, John wrote:
> > 
> > Martin writes, excerpting:
> > 
> > >   If I had to call gss_inquire_context() I really wouldn't want it
> > >   to fail with GSS_S_CONTEXT_EXPIRED (i.e. *not* return both names
> > >   and the context attributes) -- or it wouldn't be possible to
> verify
> > >   that the new security context has exactly the same
> characteristics
> > >   and same peers as the old one.
> > > 
> > >   Due to the stateless nature of gssapi, it would also be easier
> if
> > >   security context transfer with
> export_sec_context/import_sec_context
> > >   would ignore the context lifetime and not be allowed to return
> > >   CONTEXT_EXPIRED.  My implementation is currently unable to
> refresh
> > >   an already expired security context when
> export/import_sec_context()
> > >   returns CONTEXT_EXPIRED.  I even claim that you have less code
> and
> > >   complexity in both, the application and the gssapi mechanism if
> > >   export/import_sec_context() wouldn't check the context lifetime
> > >   when implementing security context refresh.
> > > 
> > I understand the motivation.  Given, however, a premise that
> mechanism
> > implementations shouldn't be required to preserve information about
> > expired contexts indefinitely, some sort of error must be possible.
> > Would it be significantly better for the state to transition
> directly to
> > GSS_S_NO_CONTEXT, without even a transient interval where
> > GSS_S_CONTEXT_EXPIRED might be returned? 
> 
> *ANY* error from export_context/import_context will stop my code from
> attempting a security context refresh.
> 
> A security context is not a self-destructing object.  There will be
> some piece of information around as long as the handle is valid and
> has not been passed to gss_delete_sec_context().  Many gssapi
> mechanisms
> are stateless service provider (libraries) that only get control when
> the application calls them.  The referenced context may be long long
> expired.  Every attempt to quantify a grace period will fail.
> 
> Only gssapi mechanisms with specific architectural characteristics
> (TCB) may have an idea about the contexts state while it is exported
> anyway.  Context transfer for TCB-oriented gssapi implementations
> that "export/import" only a reference to a context in the TCP
> is currently underspecified -- and our application does dispose of
> exported security contexts by simply memsetting them to zero
> on a regular basis.
> 
> No matter what the structure of a context is like, the gssapi
> implementation must adhere to some of the rules.  If the application
> was able to obtain a valid context handle, the handle will have to
> remain valid for as long as the application desires -- which may
> be even months or years (depending on the OS...).  The context
> referenced by that handle may expire or become unusable, the
> handle must remain valid and must be passed to gss_delete_sec_context
> by the application to be released.  I would consider the major_status
> code GSS_C_NO_CONTEXT semantically invalid for "valid handles",
> independent of the state or usability of the context.
> 
> 
> If the gssapi implementation disposes of cryptographic keys as soon
> as it notices that a context expires or becomes unusable, that is
> fine.  However I don't see a problem with keeping the flags and
> the name of both peers around, since the application is still
> supposed to call gss_delete_sec_context() to release any resources
> associated with that context handle.
> 
> 
> -Martin
>

---

From: Marc Horowitz <[email-masked]>
Date: 07 Nov 1997 14:13:10 -0500

"Linn, John" <[email-masked]> writes:

>> context's handle).

I think I agree with Martin here.  While the implementation might
clean up some state, I think that gss_inquire_context() should be
guaranteed to succeed on a context handle for which
gss_delete_sec_context() has never been called.  GC'ing keys and other
similar information asynchronously seems like reasonable
implementation behavior, particularly since since this is invisible to
the application anyway.

If the language environment is powerful enough to know when the
application has no future references to the handle (this isn't true
for C, of course), then cleaning up in this case seems reasonable,
too, but only because the implementation can guarantee that
gss_inquire_context() (nor any other context function) will ever be
called for that handle.

>> A caller might be understandably surprised, though, if it were to
>> receive a handle for a newly established context which appears
>> indistinguishable from a handle previously received and
>> corresponding to a context subsequently expired and
>> flushed. Can/should we make any statement on this issue?  What
>> assumptions have mechanism implementors made in this area?

The mit krb5 implementation can return a handle again after it has
been deleted.  So (pseudocode)

	gss_ctx_id_t h1, h2;

	h1 = do_gss_init_sec_context_loop();
	gss_delete_sec_context(h1);
	h2 = do_gss_init_sec_context_loop();

can result in h1 == h2.  This is because in this implementation, a
handle is really just a casted pointer returned from malloc().
gss_delete_sec_context() calls free() on this pointer, so a future
call to malloc() could return it again.

		Marc

---

From: "Theodore Y. Ts'o" <[email-masked]>
Date: Sat, 15 Nov 1997 20:11:01 -0500

From: "Linn, John" <[email-masked]>
   Date: Fri, 7 Nov 1997 11:31:29 -0500

I've always assumed that a mechanism was not allowed to silently flush a
context record; it has to be freed using gss_delete_sec_context().
Perhaps if not everyone has made this assumption, we should so state
this explicitly.

A very good argument against it is precisely the concern you've raised:
In an implementation where the context handle is a small integer, an
expired context could get deleted, flushed, and then reused when another
security context is created, an varaible containing a context handle
would now refer to an entirely different security context.

It's for the exact same reason that in Unix, when carrier drops on a
tty, POSIX specifies that the file descriptor is "invalidated", NOT
closed.  This is because if it were closed, the file descriptor would be
subject to reuse by the open() call, and the program which had file
descriptors pointing to the now-hung-up modem would now be silently
referencing the newly opened file.  This is Bad(tm), and so POSIX very
explicitly states what happens upon a carrier drop.  

It would probably be a good idea for us to have similar language in the
GSSAPI.

					- Ted