Access control is a method to implement one class of security policies, and to protect against a certain class of threats. However, access control alone can never provide ``security'' in a broader sense. In this section we direct our attention to what goes on between a client and a server, when information passes over a network.
The overall goal is to achieve secure communications between a client and a server. In our model, the client and the server typically reside in different address spaces, on different machines. For this reason, communications must pass over the network and are thus vulnerable to any attacker who can get physical access to the network. Within an Intranet, it might be possible to have some control over the network. However, it is unlikely that it is possible to completely protect the network against a determined attacker. In the case of the Internet, it is clearly futile to expect to have any control whatsoever over what happens to a packet en route.
Thus, we need a framework for securing inter-machine communications. We assume here that intra-machine communications, i.e. communications between objects in the same address space, can be considered secure. This is a reasonable assumption as in order for such communications to be vulnerable an attacker must gain privileged access to the machine on which they take place. Should that happen, the measures we discuss here are of little value anyhow.
From what has been outlined above, transfer of security-related information ought to take place as inter-machine communications. However, at the same time we want to collect and centralize security-related functions within a security domain, even though clients and applications are distributed. (This is both for administrative and security reasons. A centralized security system is easier to maintain and can also be secured physically.)
In our object-oriented model, we achieve these goals by introducing, at each network node, a security services proxy. This proxy has the following properties
The proxy object is thus the link between client applications and the security services.
As a generic interface to security services, GSS-API defines two important concepts, namely credentials and security contexts, that are realized as data structures by GSS-API implementations. Applications only deal with handles to objects of these types and need not be concerned with the internals. However, applications must pass between them GSS-tokens that allow the context to be maintained at both communicating endpoints.
An application calls GSS_Acquire_cred to obtain a credential handle to a set of credentials for a specified name. An application need not concern itself with authentication and authorizations for the specified identity. Either this has been establish beforehand, or GSS will instigate an authentication procedure, or the call will fail. In many cases applications need not call GSS_Acquire_cred explicitly. Where there is no ambiguity, a set of default credentials can be used.
Credentials are used to establish a security context between two parties. An application initiates secure communications by using credentials obtained by default, or by calling GSS_Acquire_cred, to establish a security context with the remote party by calling GSS_Init_sec_context. A security context contains information about the logical link between two communicating parties. Important information includes, for instance, encryption methods to be used, and the shared conversation keys to be used for encryption. The GSS-API context also contains several state variables that describe the characteristics of the context. The arguments to the call are the name of the target and some parameters describing the preferred characteristics of the context to be established. If successful, the call returns a context handle and an output token. The application is responsible for passing the output token to the remote application, which in turn is responsible for forwarding the token to the local GSS-API implementation. Internally, a context contains information needed for secure communications, such as cryptographic keys.
When a context has been established, GSS-API offers per-message protection of communications. The basic services are integrity protection and confidentiality. Integrity protection of messages is provided by the functions GSS_GetMIC and GSS_VerifyMIC (MIC stands for Message Integrity Code, see section 6.1.4), while the confidentiality service functions are named GSS_Wrap/ GSS_Unwrap. The GSS-API also supports replay detection and sequencing. If underlying mechanisms provide the necessary support, applications can receive alerts about duplicated or missing messages through GSS-API.
In addition to what has been described here, the GSS-API specification includes more functions for managing credentials and contexts. There are also a number of support functions for handling names and for getting information about the state of a context.
The GSS-API specification says very little about implementation. Through the token mechanism the specification provides a means for local GSS-implementations to pass among them the information necessary for establishing a context and performing other administrative tasks. Using tokens, it is possible to implement the GSS-API as completely autonomous local service providers.
Using the autonomous approach has advantages as well as disadvantages. Not having to rely on some central agent or service can increase flexibility and overall system robustness. On the other hand, not having any means for centrally monitoring system activities can be a security concern. For instance, without such monitoring it is very difficult to implement security policies such as separation of duty that dictates that a user must not act in two roles simultaneously.
Figure 3.3: GSS-API context management.
In our object-oriented design, where objects transparently can invoke methods on objects on remote machines, we see an opportunity to introduce a mechanism for a coordinated management of security contexts.
Figure 3.3 shows the main components in our proposed GSS-API implementation. To implement the GSS interface, there is an APA collocated Context Manager Object. The context manager keeps track of created context objects and offers an administrative interface that allows a privileged system operator to examine and manipulate active contexts. Each context is represented by a context object instance. On all client machines there must exist an instance of the GSS-API proxy object. Applications interact with this proxy object only. This makes context management completely invisible to applications.
To protect communications among GSS-API proxies, the context manager, and context objects, keys are established per context among the context object and the proxies. These transient keys can be established using preinstalled symmetric keys, through asymmetric key cryptography, or through other key exchange protocols such as Diffie-Hellman. In the two former cases, it is necessary to install locally, on each machine, a secret key for use by the GSS-API proxy object. The Diffie-Hellman protocol has the advantage of not requiring a preinstalled secret in order for two parties to agree on a session key [DH76]. However, in the absence of preinstalled keys, authentication becomes difficult.
When an application requests a security context using its local GSS-API proxy to call GSS_Init_sec_context, the proxy forwards the request to the context manager. The context manager then creates an instance of a context object that is responsible for the actual management of the context. Context objects normally exist within the same address space as the context manager. GSS_Init_sec_context returns to the initiating application a token that contains a reference to the context object. The application can now establish a communications channel to the context target, and transfer the received token there.
Upon receiving a context token, the target application should relay the token to the local GSS-API proxy of the target. This is done by calling GSS_Accept_sec_context. The target GSS-API proxy can then call upon the context object to finalize the establishment of the context. When calling one of the context-establishing functions, an application indicates which characteristics it wants the context to have. The GSS-API implementation is not required to honor such requests from an application, but should do so if possible. Even though some requests are not fulfilled, the context will still be established. It is up to the application to examine the actual characteristics of a context and then decide whether or not the context should be used.