GSS-API Programming Guide

GSS-API Tokens

The basic unit of currency, so to speak, in the GSS-API is the token. Applications using the GSS-API communicate with each other by using tokens, both for exchanging data and for making security arrangements. Tokens are declared as gss_buffer_t data types and are opaque to applications.

The two types of tokens are: context-level tokens and per-message tokens. Context-level tokens are used primarily when a context is established (initiated and accepted), although they can also be passed afterward to manage a context.

Per-message tokens are used after a context has been established, and are used to provide protection services on data. For example, if an application wants to send a message to another application, it might use the GSS-API to generate a cryptographic identifier to go along that message; that identifier would be stored in a token.

Per-message tokens can be considered with regard to “messages” as follows. A message is a piece of data that an application sends to a peer; for example, the ls command sent to an ftp server. A per-message token is an object generated by the GSS-API for that message, such as a cryptographic tag, or the encrypted form of the message. (Semantically speaking, this last example is mildly inaccurate: an encrypted message is still a message, not a token, since a token is only the GSS-API-generated information. However, informally, message and per-message token are often used interchangeably.)

It is the responsibility of the application (not the GSS-API) to:

  1. Send and receive tokens. The developer usually needs to write generalized read and write functions for performing these actions. send_token() and recv_token() are examples of such functions.

  2. Distinguish between types of tokens and manipulate them accordingly.

    Because tokens are opaque to applications, there is no difference (to the application) between one token and another. Therefore, an application must be able to distinguish one token from another without explicitly knowing their contents, before passing them on to the appropriate GSS-API functions. The ways an application can distinguish tokens include:

    • By state — that is, through the control-flow of a program. For example, if an application is waiting to accept a context, it can assume that any token it receives is a context-level token related to context-establishment, because it expects peers to wait until the context is fully established before sending message (data) tokens. After the context is established, the application can assume that any tokens it receives are message tokens. This is a fairly common way to handle tokens; the sample programs in this book use this method.

    • An application might distinguish types of tokens when sending and receiving them. For example, if the application has its own function for sending tokens to peers, it can include a flag indicating what kind of token is being sent:

      gss_buffer_t token;     /* declare the token */
      OM_uint32 token_flag       /* flag for describing the type of token */
      <get token from a GSS-API function>
      token_flag = MIC_TOKEN;     /* specify what kind of token it is */
      send_a_token(&token, token_flag);

      Then the receiving application would have a receiving function (say, “get_a_token()”) that would check the token_flag argument.

    • A third way might be through explicit tagging; for example, applications might use their own “meta-tokens”: user-defined structures that contain tokens received from GSS-API functions, along with user-defined fields that signal how the GSS-API-provided tokens are to be used.

Interprocess Tokens

The GSS-API permits a security context to be passed from one process to another in a multiprocess application. Typically, this application has accepted a client's context and wants to share it among its processes. See Context Export and Import for information on multiprocess applications.

The gss_export_context() function creates an interprocess token that contains information allowing the context to be reconstituted by a second process. It is the responsibility of the application to pass this interprocess token from one process to the other, just as it is the application's responsibility to pass tokens to other applications.

Since this interprocess token might contain keys or other sensitive information, and since it cannot be guaranteed that all GSS-API implementations will cryptographically protect interprocess tokens, it is up to the application to protect them before exchange. This may involve encrypting them with gss_wrap(), if encryption is available.

Note –

Interprocess tokens cannot be assumed to be transferable across different GSS-API implementations.