GSS-API Programming Guide

Context Initiation (Client)

Security context initiation between an application and a remote peer is done using the gss_init_sec_context() function. If successful, this function returns a context handle for the context being established and a context-level token to send to the acceptor. Before calling gss_init_sec_context(), however, the client should:

  1. Acquire credentials, if necessary, with gss_acquire_cred(). Commonly, however, the client has received credentials at login, and can skip this step.

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

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

Applications are not bound to use these default values. Additionally, the client will specify its 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 can require several “handshakes” in order to establish a context; that is, it can require the initiator to send more than one piece of context information before it considers the context 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. Thus a loop should use gss_init_sec_context()'s return value to test whether to continue the initiation loop.

The client passes context information to the server in the form of the output token returned by gss_init_sec_context(). The client receives information back from the server as an input token, which can then be passed as an argument to 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, in addition to checking for the return status of gss_init_sec_context(), the loop should check the input token's length to see if a further token needs to be sent to the server. (Before the loop begins, the input token's length should be initialized to zero, either by setting the input token to GSS_C_NO_BUFFER or by setting the structure's length field to a value of zero.)

This is what such a loop can look like, highly generalized:

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

Naturally, a real loop will be more complete, with, for example, much more extensive error-checking. See Establishing a Context (program listing in client_establish_context()) for a real example of such a context-initiation loop. Additionally, the gss_init_sec_context(3GSS) man page gives a less generic example than this.

Again, the GSS-API does not send or receive tokens; these must be handled by the application. Examples of token-transferring functions are found in send_token() and recv_token().

Here is a synopsis of gss_init_sec_context(). For more information, see the gss_init_sec_context(3GSS) man page.


Example 1–5 gss_init_sec_context()

     OM_uint32 gss_init_sec_context (
       OM_uint32                    *minor_status,
       const gss_cred_id_t          initiator_cred_handle,
       gss_ctx_id_t                 *context_handle,
       const gss_name_t             target_name,
       const gss_OID                mech_type,
       OM_uint32                    req_flags,
       OM_uint32                    time_req,
       const gss_channel_bindings_t input_chan_bindings,
       const gss_buffer_t           input_token
       gss_OID                      *actual_mech_type,
       gss_buffer_t                 output_token,
       OM_uint32                    *ret_flags,
       OM_uint32                    *time_rec )

minor_status

The status code returned by the underlying mechanism.

initiator_cred_handle

The credential handle for the application. This should be initialized to GSS_C_NO_CREDENTIAL to indicate the default credential to use.

context_handle

The context handle to be returned. This should be set to GSS_C_NO_CONTEXT before the loop begins.

target_name

The name of the principal to connect to; for example, “nfs@machinename.”

mech_type

The security mechanism to use. Set this to GSS_C_NO_OID to get the default provided by the GSS-API.

req_flags

Flags indicating additional services or parameters requested for this context. req_flags flags should be logically OR'd to make the desired bit-mask value, as in:


GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG

GSS_C_DELEG_FLAG

Requests that delegation of the initiator's credentials be permitted. See Delegation.

GSS_C_MUTUAL_FLAG

Requests mutual authentication. See Mutual Authentication.

GSS_C_REPLAY_FLAG

Requests detection of repeated messages. See Out-of-Sequence Detection and Replay Detection.

GSS_C_SEQUENCE_FLAG

Requests detection of out-of-sequence messages. See Out-of-Sequence Detection and Replay Detection.

GSS_C_CONF_FLAG

Requests that the confidentiality service be allowed for transferred messages; that is, that messages be encrypted. If confidentiality is not allowed, then only data-origin authentication and integrity services can be applied (this last only if GSS_C_INTEG_FLAG is not false).

GSS_C_INTEG_FLAG

Requests that the integrity service be applicable to messages; that is, that messages may be stamped with a MIC to ensure their validity.

GSS_C_ANON_FLAG

Requests that the initiator remain anonymous. See Anonymous Authentication.

time_req

The number of seconds for which the context should remain valid. Set this to zero (0) to request the default.

input_chan_bindings

Specific peer-to-peer channel identification information connected with the security context. See Channel Bindings for more information about channel bindings. Set to GSS_C_NO_CHANNEL_BINDINGS if you don't want to use channel bindings.

input_token

Token received from the context acceptor, if any. Should be initialized to GSS_C_NO_BUFFER before the function is called (or its length field set to zero).

actual_mech_type

The mechanism actually used in the context. Specify NULL if you don't need to know.

output_token

The token to send to the acceptor.

ret_flags

Flags indicating additional services or parameters requested for this context. ret_flags flags should be logically AND'd to test the returned bit-mask value, as in:


if (ret_flags & GSS_C_CONF_FLAG)
     confidentiality = TRUE;

GSS_C_DELEG_FLAG

If true, indicates that the initiator's credentials can be delegated. See Delegation.

GSS_C_MUTUAL_FLAG

If true, indicates that mutual authentication is allowed. See Mutual Authentication.

GSS_C_REPLAY_FLAG

If true, indicates that detection of repeated messages is in effect. See Out-of-Sequence Detection and Replay Detection.

GSS_C_SEQUENCE_FLAG

If true, indicates that detection of out-of-sequence messages is in effect. See Out-of-Sequence Detection and Replay Detection.

GSS_C_CONF_FLAG

If true, confidentiality service is allowed for transferred messages; that is, that messages can be encrypted. If confidentiality is not allowed, then only data-origin authentication, and integrity services can be applied (this last only if GSS_C_INTEG_FLAG is not returned as false).

GSS_C_INTEG_FLAG

If true, the integrity service can be applied to messages; that is, that messages can be stamped with a MIC to ensure their validity.

GSS_C_ANON_FLAG

If true, indicates that the context initiator will remain anonymous. See Anonymous Authentication.

GSS_C_PROT_READY_FLAG

Sometimes context establishment can take several passes, and sometimes the client might have to wait before it's complete. Even though a context is not fully established, gss_init_sec_context() can indicate what protection services, if any, will be available after the context is complete. An application can therefore buffer its data, sending it when the context is eventually fully established.

If ret_flags indicates GSS_C_PROT_READY_FLAG, the protection services indicated by the GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG flags are available even if the context has not been fully established (that is, if gss_init_sec_context() returns GSS_S_CONTINUE_NEEDED). An application can then call the appropriate wrapping functions, gss_wrap() or gss_get_mic(), with the preferred protection services, and buffer the output for transfer when the context is complete.

If GSS_C_PROT_READY_FLAG is false, then the application cannot make any assumptions about data protection, and must wait until the context is complete (that is, when gss_init_sec_context() returns GSS_S_COMPLETE).


Note –

Earlier versions of the GSS-API did not support the GSS_C_PROT_READY_FLAG argument, so developers wanting to maximize portability should determine which per-message services are available by looking at the GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG flags after a context has been successfully established.


GSS_C_TRANS_FLAG

This flag indicates whether this context can be exported. For more information on importing and exporting contexts, see Context Export and Import.

time_rec

Number of seconds for which the context will remain valid. Specify NULL if you're not interested in this value.

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

gss_init_sec_context() returns GSS_S_COMPLETE if it completes successfully. If a context-establishment token is required from the peer application, it returns GSS_S_CONTINUE_NEEDED. If there are errors, it returns error codes, which can be found on the gss_init_sec_context(3GSS) man page.

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