Silicon Graphics, Inc.
OpenVault
Interprocess Communication
and
Authentication
Design Document
$Id: commlib.html,v 1.13 1997/07/01 21:38:29 curtis Exp $
Overview/High Level Goals
OpenVault interprocess communication requires both the OpenVault server and
clients to be able to exchange information. Typically, clients will
make requests of the server to perform some service and the server will
send one or more replies indicating the disposition of the client's
request. The server will also need to send information asynchronously
to the client representing status information, revocation information,
and possibly additional information in the future.
OpenVault authentication requires that there be a mechanism in place to
authenticate the OpenVault client to the OpenVault server and vice
versa. Without such a mechanism, a potential attacker could insert
rogue processes pretending to be legitimate clients or servers and thus
subvert the integrity of the system and the data which it serves.
OpenVault authentication is purposely limited to client and server
authentication only; no user authentication is performed by the
OpenVault server.
Decisions/Assumptions/Limitations
OpenVault is initially targeted to run on SGI hardware running Irix 5.3
and later operating systems. However, no limitations have been placed
on the design which would prevent it from being ported to other POSIX-
compliant implementations of Unix with a minimum of effort. Ports to
operating systems other than Unix may be possible, but their
consideration has been given a low priority in the current design.
From the standpoint of security and authentication, there is much to be
said in favor of using an established authenticated key exchange
mechanism combined with strong encryption in order to secure
communications between the OpenVault server and its clients. However,
due to anachronistic U.S. export laws regarding cryptography, such an
implementation would be a sure route to a U.S.-only product. Since SGI
does a great deal of international business, this was judged to be a
poor compromise. It is still possible to secure the benefits of
authentication and prevent a potential attacker from masquerading as an
OpenVault process by using message integrity codes. Although all
OpenVault communications will have to be clear (e.g. unencrypted), this
allows the possibility of remaining within the limits of U.S. export
law.
Functional Specification
Interprocess Communication
Since OpenVault relies on a client/server model, some means must be
provided for clients to communicate with the server. This is where
interprocess communications requirements originate. There must exist a
simple client interface to allow clients to make requests of the server
in either a synchronous or asynchronous manner. Furthermore, some
provision must be made for the server to communicate information
asynchronously to the client. Since clients and servers will initially
be running on Unix-based machines connected by a network, the
requirements for interprocess communications can be further refined to
specify the use of a generic Unix network communications interface at
the lowest level.
Authentication
Communications channels must be authenticated and message integrity
assured. There must be a high level of confidence that a particular
communications channel originates with a particular host. Further,
there must be a high level of confidence that the data that flows over
the communications channel has not been altered by any intervening
hosts while enroute to its destination.
Implementation
Client Side Server Side
+--------------------+ +--------------------+
| Client Application |<-OpenVault cmds->| Server Functions |
+--------------------+ +--------------------+
| |
+--------------------+ +--------------------+
| Authentication |<---ov layer----->| Authentication |
+--------------------+ +--------------------+
| |
+--------------------+ +--------------------+
| Comm Layer |<---mlm layer--->| Comm Layer |
+--------------------+ +--------------------+
Figure 1 -- OpenVault Client/Server Interprocess Communication
Overview
There are three logical layers to the client side as illustrated in
Figure 1 above. The top layer is the application layer. At this
level, OpenVault commands are exchanged between the client and the
server. The next layer is the OpenVault session layer and is implemented
in the libov.a library. This layer handles mutual authentication,
key management, and message integrity checking if it is enabled. The
bottom layer is the OpenVault transport layer and is also implemented in
the libov.a library. This layer handles the transport of raw messages
between the client and the server via operating system calls.
Client Application Layer
The KISS principle was used in the design of the client application
layer. Client applications need only concern themselves with six
library calls to handle all of their communications needs with the
server. A list of the functions follows: ov_open(), ov_send(),
ov_recv(), ov_close(), ov_perror(), and free_result(). These
functions are all implemented in the OpenVault client library, libov.a.
Applications wishing to use these functions must link with this
library and include the ov_lib.h include file. An overview of these
functions follows.
-
ov_handle_t *ov_open(char *app_name, char *hostid, int flags)
-
This function takes three arguments. The first is a string containing
the name of the application. The second is a string containing the
hostname (or hostid) of the host on which the OpenVault server is
running. The third argument is a flags argument. The function returns
a pointer to a ov_handle_t structure. This structure contains opaque
internal state information as well as several user accessible values
including an integer and string with status information.
-
ov_send(ov_handle_t *handle, char *command, int timeout)
-
This function takes three arguments. The first is a pointer to a
ov_handle_t structure which must have previously been returned by an
earlier call to ov_open(). The second argument is a string containing
ASCII commands to be send to the OpenVault server. The third argument
is an integer timeout value. ov_send() returns an integer error value
which contains zero if there was no error.
-
result_t *ov_recv(ov_handle_t *handle, int timeout)
-
This function is used to receive commands from the OpenVault server.
It takes two arguments, a pointer to a ov_handle_t structure which must
have been returned by a previous call to ov_open() and an integer
timeout value. ov_recv() returns a ov_result_t structure. This
function returns any pending message from the OpenVault server of if
there are none waits up to the specified number of seconds for a
message from the server before returning a timeout error. If
successful, the ov_result_t structure will contain an ASCII message in
it as well as a status integer with a value of OV_STATUS_OK (0).
Otherwise, the status integer will be set to a negative value set to be
equal to the type of error encountered.
-
ov_close(ov_handle_t *handle)
-
This function takes one argument. It is a pointer to a ov_handle_t
structure which must have been returned by an earlier call to
ov_open(). ov_close() frees the resources allocated by the ov_open()
command and returns an integer error value which contains OV_STATUS_OK
if there was no error, otherwise a negative error value.
-
void ov_perror(char *s, int err)
-
This function takes two arguments. The first is a string which is
used to generate a message of the form : .
The second is a negative error value returned by any of the OpenVault
library calls. The function will generate an error message corresponding
to the type of error represented by the second argument and print it
to the standard error device.
-
void free_result(result_t *result)
-
This function is used to free the result_t structure returned by
the ov_recv() function. The ov_recv() function allocates memory to
hold the result_t structure it returns. In order to free the
memory used by this structure, this function should be called with a
pointer to the result_t structure to be freed as the single
argument.
Authentication Layer
Initialization
Authentication occurs once a communications channel has been
established between the initiator and the recipient. For illustrative
purpose, we're going to assume that Alice represents the process that
initiates communications with the OpenVault server (e.g. a client
application, admin application, DCP, or LCP). Bob will represent the
OpenVault server.
The authentication process begins with Alice sending her name to Bob.
Bob replies by generating a 32-bit random number (R1) and sending it to
Alice as a challenge. Upon receiving this number, Alice encrypts it
with the key she shares with Bob and sends this value, along with
another 32-bit random number she has generated herself (R2) to Bob.
After checking to make sure that Alice has successfully encrypted R1,
Bob then encrypts R2 and generates a third random number (R3). Bob now
sends the encrypted R2 and encrypted R3 to Alice. Alice verifies that
R2 has been properly encrypted and then decrypts R3 and stores it as
the session key.
Command execution
If Alice wants to send a message to Bob, she must send him two values.
The first value is the message itself. The second value is the Message
Integrity Code (MIC) for the message. The MIC is generated by using a
cryptographically strong hash algorithm (such as MD5) to hash the
message and then encrypting the resulting hash with the session key
obtained during the authentication phase.
Upon receiving Alice's request, Bob computes the MIC of the message
string, encrypts it with the session key, and compares it to the MIC
received with the message string. If the two values match, message
integrity is assured.
In order to increase the resistance of the above paradigm to a type of
attack known as a playback attack, the session key could be incremented
by one (or otherwise modified in a deterministic fashion) after each
successful transaction at both Alice's end and Bob's end.
Client Programming Example
#include
#include
#define OV_HOST "openvault.engr.sgi.com"
#define MYAPPNAME "name_of_my_application"
main(int argc, char *argv[])
{
int status;
ov_handle_t *handle;
result_t *result;
/*
* Initiate communication with the server running on
* the host specified by OV_HOST. Register under application
* name specified by MYAPPNAME. Authentication is performed
* transparently to the client. A handle is returned which
* containes opaque data used by the OpenVault client interface
* library in addition to an error value and reply string.
*/
handle = ov_open(MYAPPNAME, OV_HOST, 0);
if (handle->status != OV_STATUS_OK) {
ov_perror("ov_open", handle->status);
exit(1);
}
/*
* Send a test message to the server.
*/
if ((status = ov_send(handle, "test 1", 5)) != OV_STATUS_OK) {
ov_perror("ov_send", status);
exit(1);
}
/*
* Look for a reply from the server for up to 5 seconds.
* Display the reply if we get it in time.
*/
result = ov_recv(handle, 5);
if (result->status != OV_STATUS_OK) {
ov_perror("ov_recv", result->status);
exit(1);
}
printf("Received reply \"%s\"\n", result->result);
free_result(result);
/*
* Send a test message to the server.
*/
if ((status = ov_send(handle, "test 2", 5)) != OV_STATUS_OK) {
ov_perror("ov_send", status);
exit(1);
}
/*
* Look for a reply from the server for up to 5 seconds.
* Display the reply if we get it in time.
*/
result = ov_recv(handle, 5);
if (result->status != OV_STATUS_OK) {
ov_perror("ov_recv", result->status);
exit(1);
}
printf("Received reply \"%s\"\n", result->result);
free_result(result);
/*
* When we are finished issuing requests to the server, we
* should call the ov_close() function to free system resources
* allocated by the earlier call to ov_open().
*/
ov_close(handle);
exit(0);
}
Interfaces
Internal Interfaces
None.
External Interfaces
There are two external interfaces for the OpenVault IPC library. The
client side interface, represented by the ov_*() calls described above,
and the OpenVault server interface. The OpenVault server interface is
currently implemented by TCP domain sockets. This provides a reliable
streams-based interface between OpenVault client processes and the
OpenVault server.