Securing Sockets with OpenSSL (Part 1)
The Internet is not for the weak-hearted programmer and designer. Today more than ever, you as a professional have to outwit and out-think some of the brightest and most devious minds. In fact, people, companies, and governments have set up public and private agencies for tracking and tracing "cyber-perps" (or crackers), a new kind of crime in which agent and cracker may never see each other's faces. In spite of the gotchas, however, network programming is hot and will continue to be so for many years to come.
The whole arena of cyber-this and cyber-that revolves around the Internet, and the Internet uses TCP/IP as its mainstay protocol. My earlier articles described TCP (or streaming protocols) and UDP (or datagram protocols). These protocols provide the brick and mortar of the Internet arena. On top of the brick and mortar lie several additional protocols that provide authentication, session management, and virtual services.
This is the first of a two-part series covering the issues and terminology in message security. The second part shows examples of how to write secure clients and servers, leveraging the concepts from my earlier article on TCP programming.
Differentiating the Authorities
The higher network functions of the Application Programming Interface (API) usually depend on TCP's reliable communications channel. Two exceptions are Network File System (NFS), which uses the faster datagram protocols, and Remote Procedure Calls (RPCs), which let you choose either TCP or UDP. Higher-level or application layer tools use streaming connections (see Figure 1). The reason is clear: TCP provides reliability, unlimited message size, and an implicit client authentication. This authentication is due to the fact that the two computers are virtually connected in a session; as long as the connection is uninterrupted, a program usually can assume that the messages it's getting come from the same program that started the session. That's a big assumption.
Figure 1 The Internet Protocol's API layers.
Many of the application-layer programs use some form of security. Security attempts to ensure that the sender, receiver, and data have varying levels of reliability, integrity, and privacy. To accomplish this, security has three main pillars: authentication, authorization, and certification:
Authentication is basically "I am so-and-so," and typically uses a username/password-style. If the user knows the name and password, most systems assume plausible authentication.
Authorization associates the user with certain privileges. The authorities file on the operating system describes the permissions that an active (online) and inactive (offline) user may have. Linux (like other UNIXes) uses user/group/world permissions, and Windows uses Access Control Lists (ACLs). When you use Telnet, an application-layer program, it ties your authentication with your authorization. In other words, when you log in, the server assigns your authorities as part of authentication.
Certification, on the other hand, requires a little more explanation. Both authentication and authorization are pretty straightforward. As noted above, some systems assume that just because the client program provides username/password or is still connected to the server, the client is really who it says it is. This is a dangerous programming assumption to make, for example, when writing transaction protocols for banking transfers.
Certification requires a trusted third party that holds information about each subscriber. This information, or certificate, affirms that the holder is really who it says it is (and the program can check this through the trusted third party). The certificate holds several pieces of information: holder name, issuer, expiration date, and so on. This certificate is signed in a process similar to watermarking checks, which demonstrates authenticity.
The certification process participates centrally in the secure connection. Each piece of the certificate plays a role in how the client and server set up their trust, or secure link. The three pillars of security work with each other to define the stages and processes that a connection must pass through to establish each party. The network programming wholly depends on these pillars.