Developer's Guide to Oracle Solaris Security

Initiating a Context in GSS-API

The gss_init_sec_context() function is used to start a security context between an application and a remote peer. If successful, this function returns a context handle for the context to be established and a context-level token to send to the acceptor.

    Before calling gss_init_sec_context(), the client should perform the following tasks:

  1. Acquire credentials, if necessary, with gss_acquire_cred(). Typically, the client receives credentials at login. gss_acquire_cred() can only retrieve initial credentials from the running operating system.

  2. Import the name of the server into GSS-API internal format with gss_import_name(). See Names in GSS-API for more information about names and gss_import_name().

When calling gss_init_sec_context(), a client typically passes the following argument values:

Applications are not bound to use these default values. Additionally, a client can specify requirements for other security parameters with the req_flags argument. The full set of gss_init_sec_context() arguments is described below.

The context acceptor might require several handshakes to establish a context. That is, an acceptor can require the initiator to send more than one piece of context information before the context is fully established. Therefore, for portability, context initiation should always be done as part of a loop that checks whether the context has been fully established.

If the context is not complete, gss_init_sec_context() returns a major status code of GSS_C_CONTINUE_NEEDED. Therefore, a loop should use the return value from gss_init_sec_context() to test whether to continue the initiation loop.

The client passes context information to the server in the form of the output token, which is returned by gss_init_sec_context(). The client receives information back from the server as an input token. The input token can then be passed as an argument in subsequent calls of gss_init_sec_context(). If the received input token has a length of zero, however, then no more output tokens are required by the server.

Therefore, besides checking for the return status of gss_init_sec_context(), the loop should check the input token's length. If the length has a nonzero value, another token needs to be sent to the server. Before the loop begins, the input token's length should be initialized to zero. Either set the input token to GSS_C_NO_BUFFER or set the structure's length field to a value of zero.

The following pseudocode demonstrates an example of context establishment from the client side.

context = GSS_C_NO_CONTEXT
input token = GSS_C_NO_BUFFER

do

     call gss_init_sec_context(credential, context, name, input token, 
                                           output token, other args...)

     if (there's an output token to send to the acceptor)
          send the output token to the acceptor
          release the output token

     if (the context is not complete)
          receive an input token from the acceptor

     if (there's a GSS-API error)
          delete the context

until the context is complete

A real loop would be more complete with more extensive error-checking. See Establishing a Security Context With the Server for a real example of such a context-initiation loop. Additionally, the gss_init_sec_context(3GSS) man page provides a less generic example.

In general, the parameter values returned when a context is not fully established are those values that would be returned when the context is complete. See the gss_init_sec_context() man page for more information.

If gss_init_sec_context() completes successfully, GSS_S_COMPLETE is returned. If a context-establishment token is required from the peer application, GSS_S_CONTINUE_NEEDED is returned. If errors occur, error codes are returned as shown in the gss_init_sec_context(3GSS) man page.

If context initiation fails, the client should disconnect from the server.