This is the first in a series of posts about a specific implementation of a secure IPC solution for OS X.
First, what do I mean by secure IPC? IPC is the communication between two or more processes on a single computer. There are many methods for doing IPC, some are applicable to most operating systems and others can be quite specific. On OS X, the most obvious choices for IPC are:
In each of these cases, lets assume there is a server process running with elevated privileges that handles requests from one or more client processes. In a typical IPC setup, the server waits for instructions from the client to perform a task. None of the three methods have the ability to establish the sender's identity "built-in." Thus, a malicious process could communicate with the server and get it to do undesirable things. Identifying the sender will be covered later in the series.
You might be thinking there are well-documented industry standard ways to secure client-server communication, in use in important applications like online banking. These methods employ public-key cryptography to ensure the privacy of the communication as well as the identities of the communicating parties. This hinges upon a malicious user not having access to the private key, in other words it is security based on what-you-know. On a single computer, what-you-know security fails because the programmer has to assume that no secrets will remain secret for very long if they are installed on a user's machine (for instance, an embedded private key can be extracted from the binary). The alternative is security based on who-you-are.
For my purposes, the data being transferred between the processes did not need to be encrypted, only the identity of the communicating parties needed to be confirmed. Both OS X and Windows have the ability to establish the identity of an application using code-signing. Thus, the goal of secure IPC, for my purposes, can be thought of as, retrieving and validating the code-signature of the processes participating in IPC.
Part 2 will deal with determining the identity of these processes at run time.