Chapter 7. Smart Card Infrastructure

Previous chapters have dealt primarily with the various aspects of smart cards that govern their construction, their communications, and the functions that they perform. As anyone well versed with personal computer (PC) architectures knows, this is obviously only part of the story. The manner in which smart card readers are integrated into PC systems and the manner in which, through them, PC applications communicate with smart cards in order to accomplish some higher level application, has been a fertile ground for standardization efforts as well.

The problem is one of providing data interchange between two applications running on two different computer systems, which are physically connected by a communication channel. In Figure 7.1, we illustrate the generic connection that needs to be supported. The smart card constitutes one independent computer system. We have software running on this computer which performs some set of functions needed by an application running on a second computer; in the case shown in Figure 7.1, it is a laptop computer. The physical channel connecting the two computers is supported by a smart card reader that connects to an I/O channel from the laptop; perhaps a serial port. The smart card, when inserted into the smart card reader, then completes the two computer interconnect.

Smart card to PC interconnect.

Figure 7.1. Smart card to PC interconnect.

We've alluded to the fact that this interconnect between two computers fits the OSI reference model for communication protocols. This model is a guiding factor in establishing the architecture of a “smart card stack” within the PC system software. By way of this protocol stack, an application at the top of the stack can send to and receive information from the smart card computer. The architecture doesn't resolve to the perfect seven-layer model, but then real-world implementations rarely exactly match our idealized models. So, in this chapter, we're going to examine the establishment of a variety of smart card stacks for various computer systems into which we want to introduce smart cards.

As with any large-scale system these days, the goals of standardization are in the eye of the beholder. That is, if representatives from a number of different technical areas address the problem, they'll each typically try to relegate the other technologies to “commodity stuff.” Such is the way it is with smart cards in large-scale application systems. In the case of PC systems, the standardization efforts have the implicit goal of arriving at an architecture as illustrated in Figure 7.2. Further, the goal is that the standardization then:

  • Make all smart card readers be vendor neutral—. an application should be able to work with any vendor's smart card reader.

  • Make all smart cards be vendor neutral—. an application should be able to make use of smart cards provided by different vendors.

Desired PC interconnect architecture.

Figure 7.2. Desired PC interconnect architecture.

We see in Figure 7.2 that we'd like to support many applications running on the PC, each of which wants to independently access a smart card. We'd like for each application to be able to use an API to establish a connection to a specific smart card. The API for each smart card should have the services of the general operating system at its disposal in order to effect the desired connection with a specific smart card that is plugged into a specific smart card reader. We don't want to have to deal (at the application level) with any eccentricities of this specific smart card reader; we'd like the smart card protocol stack to make all the readers look the same.

Smart card readers are not standard elements of PC architectures. Rather, we have varieties of smart card readers that interface to PCs through standard I/O ports into the PC system; perhaps a serial port, perhaps a parallel port, perhaps some other. We expect the differences between the specific I/O port used and the specific smart card reader connected to that port, to be “normalized” by a standard device driver architecture within the operating system. Thus, again looking at Figure 7.2, a specific application connects to a specific smart card by using the intervening PC system as a general switch.

If one happens to manufacture smart card readers, or smart cards for that matter, and standardization washes out all prospects for product innovation to distinguish competitors from each other, then you have a pretty poor reason for being in the business. So, the trick is to establish standards to stabilize the marketplace and avoid application systems being forced into single source situations. However, the standards must allow sufficient space for product differentiation. These are the guiding principles of most standardization efforts, be they driven by international standards bodies, industry consortia, or even individual companies. Of course, it's the continued efforts of a wide range of participants that keeps the process (in some fashion) “honest.”

Smart Card Protocol Stacks

Every smart card vendor, for many years now, has provided a proprietary software package that will allow its smart cards and smart card readers to be used on general-purpose computer systems. Over the last several years, however, a number of efforts have been initiated to develop “standard” smart card software stacks on a variety of general computer platforms. The best known and most successful of these efforts are the

  • Personal Computer/Smart Card (PC/SC) Workgroup

  • Open Card Framework (OCF)

  • Small Terminal Interoperability Platform (STIP)

In Chapter 5, we discussed another specification called EMV. EMV is a specification for both off-card and on-card environments developed as a joint effort by Europay, MasterCard, and Visa. The specification is aimed at infrastructures for large-scale deployment of multiapplication cards based around financial transaction systems. EMV finds its way into all of the general PC-based infrastructures that we've mentioned here through the manner in which applications are named (on multiapplication cards), the way that they are accessed on multiapplication cards, and in electrical characteristics. We won't cover the EMV terminal specifications further in this book, choosing rather to concentrate on the more general smart card stacks that you'll likely encounter in smart card applications developed for general purpose computing platforms. The EMV application access methods were discussed in Chapter 5.

The OCF effort has evolved into an excellent open source platform for supporting smart cards on full-scale Java-oriented computing platforms. A quite good description of OCF is found in the book, Smart Card Application Development Using Java (Hansmann et al. 2000).

The PC/SC effort has evolved a smart card stack that has proven applicable to a variety of general computer platforms, and it will be the focus of our considerations in this chapter.

The STIP effort is aimed (as the name implies) at small terminal platforms, developed in Java; it is gaining popularity among terminal manufacturers. This specification is being developed through close cooperation between the STIP group and the Global Platform consortium. In the following sections, we'll primarily consider the PC/SC architecture along with a brief overview of the STIP architecture.

PC/SC

Led by Microsoft, a team of PC and smart card manufacturers including CP8 Transarc, Hewlett-Packard, Schlumberger, and Siemens-Nixdorf defined a general-purpose architecture for including smart card support in PC systems. The specification for this architecture was first published in December 1996 and is called the Interoperability Specification for ICCs and Personal Computer Systems. It has come to be known as simply PC/SC.

A primary purpose of the PC/SC architecture and specification is to enable card reader manufacturers and smart card manufacturers to develop products independently but have the results of their efforts work together smoothly. As a result of this effort, application programmers can build smart card applications that aren't tied to particular readers or cards, and system builders can mix and match readers and cards freely.

The approach used, as illustrated in Figure 7.3, involves three distinct software layers within the PC operating system. First, a series of modules each provides an API that closely corresponds to the command set supported by a specific smart card. At its simplest, each module presents a method through which an application program can send a specific APDU to a smart card where it will be executed and the results conveyed back to the application. These API modules are termed “smart card service providers” (SSP, where smart card is treated as one word, not two). We might expect to find one SSP for each smart card to be used by a PC system.

The PC/SC architecture.

Figure 7.3. The PC/SC architecture.

When an application accesses an SSP, the SSP provides services to generate an APDU to convey a specific command to a specific smart card. These APDUs are conveyed, by way of a well-defined API, to a second software layer within the smart card stack called the smart card resource manager. The resource manager is a broker, or a traffic cop if you will, which serves to route APDUs from an SSP to the device driver for a smart card reader into which the desired smart card is inserted. SSPs talk to the resource manager through a standard API and the resource manager talks to the device drivers for the smart card readers through a standard API. Consequently, the resource manager can connect an SSP to a smart card inserted into any available smart card reader. The readers are interchangeable.

The third layer of this smart card stack is then a set of device drivers for each smart card reader. The device drivers have to normalize away any differences between the specific I/O channels being used by the smart card reader and then be able to communicate directly with the smart card reader.

Figure 7.3 illustrates the fundamental structure of the PC/SC smart card architecture.

The PC/SC architecture defines the interface between smart card readers and the resource manager so that, from the application's point of view “looking through” the resource manager, all smart card readers look and behave the same. A smart card reader manufacturer provides along with its smart card reader hardware a PC/SC driver that connects the reader hardware to the resource manager. Thus, a smart card reader is treated by the system just like a floppy disk reader or a CD-ROM reader. The only difference is that you put a smart card into it rather than a floppy disk or a CD-ROM.

Because smart card readers vary more widely and can contain more functionality than a simple floppy disk reader, there is a provision in the PC/SC architecture for the application program to communicate directly with the smart card reader in addition to communicating with the smart card that it contains. This capability is indicated by the line (in Figure 7.3) directly between the application and the resource manager. This interface could be of use when, for example, the smart card reader is an automatic teller machine (ATM) or a point-of-sale (POS) terminal.

The actual application programming interface (API) seen by the smart card application is provided by the smart card service provider (SSP). This interface can be card specific, domain specific, or completely general purpose. The PC/SC specification includes a description of the general-purpose interface, which includes card authorization, PIN verification, file access, and cryptographic services. The goal of the SSP is to make it appear that a PC application is talking directly to a smart card, as illustrated in Figure 7.4.

Functional goal of a smart card service provider.

Figure 7.4. Functional goal of a smart card service provider.

Card-specific PC/SC smart card service providers are typically written by smart card manufacturers and included with the cards themselves. Thus, for example, Gemplus provides an SSP for each of its off-the-shelf cards, as do Schlumberger and Oberthur. Minimally, these card-specific SSPs make each command supported by the card available to the application in an easy-to-use manner. Some also support some higher level functionalities that can be built from the basic commands.

As smart card application domains become more well defined through various standards and specification efforts, SSPs that support these standards and specifications have appeared. Thus, for example, we now have Java Card SSPs along with digital signature SSPs. These domain-specific SSPs not only support the processing and procedures that are characteristic of the domain, but they assume cards that contain the data structures and computing capabilities that are specified for the domain. Domain-specific SSPs are prime business opportunities for third-party smart card software companies.

A Simple SSP API

For purposes of looking at an SSP in a bit more detail, let's assume that we have a smart card which essentially supports an ISO 7816-4 command set, such as we discussed back in Chapter 4 or perhaps even the Cryptoflex card we considered in Chapter 6. This command set supports a number of security commands as well as an on-card file system and a command set to access this file system. This simple SSP API serves more as an example of how to build SSPs than it does as a commercially available and widely used smart card API. Figure 7.5 illustrates the general layout of this API. An SSP can be oriented at a specific smart card or a specific class of smart card. This class of smart card is comprised of a fixed command set with typical commands for providing smart card security functions and file access functions. In addition, the Cryptoflex smart card provides cryptographic services and these are generally available through the API as well. As we'll see a bit later in this chapter, there are at least two well-defined software modules for using tokens (smart cards) in support of general cryptographic operations. These modules require a more specific API than is considered here.

A simple smart card service provider API architecture.

Figure 7.5. A simple smart card service provider API architecture.

SCARD connects to the card and maintains a context in which the other functions can operate. It has two functions, AttachByHandle and AttachByIFD, that let the application specify a card to access and two more functions, Detach and Reconnect, to administer this connection.

The CARDAUTH interface provides functions to enable the card to authenticate the application and the application to authenticate the card. Included on this very generic interface are GetChallenge, ICC_Auth, APP_Auth, and User_Auth. GetChallenge returns a random data string from the card that is to be encrypted by the application and returned in the APP_Auth call. ICC_Auth sends a random string to the card that is to encrypt it and return it. Finally, User_Auth is a general interface to vendor-specific routines for user authentication.

CHVERIFICATION is a collection of functions that connect to PIN functionality on a smart card. The functions on the interface are Verify, ChangeCode, Unblock, and ResetSecurityState. Verify presents a PIN to the card and returns success or failure. ChangeCode allows the cardholder by way of the application to change the card's PIN. Unblock lets the card's issuer unblock a PIN that has become blocked through too many unsuccessful attempts to present a PIN. Finally, ResetSecurityState causes a vendor-specific resetting of the PIN security on the card.

The FILEACCESS routines present the expected set of functions for manipulating files on the card. They are

  • ChangeDir—. Changes to a different directory.

  • GetCurrentDir—. Returns the name of the current directory.

  • Directory—. Returns a list of the files in the current directory.

  • GetProperties—. Returns the properties of the current file.

  • SetProperties—. Sets the properties of the current file.

  • GetFileCapabilities—. Gets capabilities of the current file.

  • Open—. Opens a file for access and makes it the current file.

  • Close—. Closes the current file.

  • Seek—. Files a data pattern in the current file.

  • Write—. Writes data into the current file.

  • Read—. Reads data from the current file.

  • Create—. Creates a file in the current directory.

  • Delete—. Deletes a file in the current directory.

  • Invalidate—. Marks a file as unavailable.

  • Rehabilitate—. Marks a file as available.

Finally, CRYPTPROV supports some basic routines for accessing cryptographic services on a smart card. It is not the full-fledged Microsoft Crypto graphic Services API (CAPI), but rather is a smart card–centric subset of CAPI that is nonetheless quite useful for adding smart card–provided cryptographic services to an application. Functions on the CRYPTPROV interfaces are

  • Decrypt—. Decodes an encrypted data block using a specified key.

  • DeriveKey—. Creates keys from fixed data.

  • Encrypt—. Encodes a data block using a specified key.

  • Export—. Returns a key stored on the smart card.

  • GenKey—. Creates keys from random data.

  • GetParm—. Returns parameters being used by the routines.

  • GetRandom—. Returns random bytes.

  • GetUserKey—. Returns the public key.

  • HashData—. Computes the cryptographic hash of a stream of data.

  • HashSessionKey—. Computes the cryptographic hash of a key.

  • ImportKey—. Provides a key to the smart card.

  • SetParam—. Sets the parameters being used by the routines.

  • SignHash—. Computes the signature on a hash using an asymmetric key.

  • VerifySignature—. Verifies the signature of a hash using an asymmetric key.

The Smart Card Protocol Stack

The SSP that we considered in the previous section will prepare a set of APDUs to be conveyed to the smart card. In terms of the OSI reference model, we will think of the SSP API as an application level interface and the APDUs as the presentation layer interface. Let's now consider the rest of the smart card protocol stack from the bottom up.

In Figure 7.6, we see the elements of the PC/SC smart card protocol stack, which corresponds to the link-level layer of the OSI Reference Model. The PC I/O channel, the smart card reader, and its connection to the contact faceplate on the smart card establishes the physical layer of the stack. TPDU packets constructed within the smart card reader driver as part of its support of the T=0 or T=1 protocol are passed across this physical layer to the T=0 or T=1 software within the smart card ICC.

Link and physical layers of the smart card protocol stack.

Figure 7.6. Link and physical layers of the smart card protocol stack.

As we mentioned earlier, the smart card resource manager acts much like a traffic cop in the smart card protocol stack. Through commands from the application, the resource manager seeks to establish a link between itself and a specific smart card reader device driver, and hence on to the specific smart card. So, in terms of the OSI reference model, the connection between the resource manager and the APDU dispatcher (if you refer all the way back to Figure 3.6) is essentially a session layer connection, which is illustrated in Figure 7.7. Our ability to effect a switched network connection is found in the fact that we can extract a smart card from one reader and insert it into another reader and then have the resource manager select the smart card reader device driver for that reader. Thus, the transport and network layers of our protocol really degenerate into an essentially fixed pathway.

Session layer interconnect of the smart card protocol stack.

Figure 7.7. Session layer interconnect of the smart card protocol stack.

In Figure 7.7, we see the illustration of this session layer connection. APDUs (the presentation layer protocol) are passed from the smart card resource manager to the APDU dispatch code on the smart card. On the smart card at that point, the APDU is interpreted and the information passed to the command processor for the command corresponding to that APDU. The command is executed on the smart card by application-level code. The results of the command execution are then repacked into a response APDU structure and returned through the smart card protocol stack to the application code on the PC. This is all illustrated in Figure 7.8.

Application layer interconnect of the smart card protocol stack.

Figure 7.8. Application layer interconnect of the smart card protocol stack.

The end result from the PC/SC architecture is very much what was originally desired. We can indeed write PC smart card applications that don't have to worry about the details of which smart card reader is going to be used. Further, by swapping out SSPs, it is possible to move a PC application from using one specific smart card to then use a different smart card. We'll see this explicitly in a later section when we look at cryptographic services provided through the smart card stack.

Unix PC/SC Architecture

The reference implementation for the PC/SC Specifications was built for Windows™ platforms and is now shipped with most Windows™ based systems. The wide introduction of smart cards into the personal computer and workstation arena has posed the issue of support for a number of platforms that are not as widely used as standard Windows™ systems; platforms such as the Macintosh™, Solaris™, Linux™, and other operating systems. Many corporations have a large number of these platforms that are used for specific applications, and support for these platforms is highly desirable. At first, most solutions for these platforms were proprietary and included vertical stacks that worked only with the solution providers' hardware provided.

As a work product of the PC/SC Workgroup, documentation was provided to describe the behavior of how a resource manager for smart cards and cryptographic devices should behave, independent of the PC operating system. Initial developers' packages for PC/SC included API documentation of actual function calls that applications could make to access anonymous smart card reader devices in an abstract fashion. The PC/SC standard provided an opportunity for other platforms to support smart cards in a way that would be compatible on Windows™ platforms. In one non-Windows environment, a PC/SC stack was created by the Movement for the Use of Smart Cards in a Linux Environment (MUSCLE) group (www.linuxnet.com) initially to work on the Linux platform. Subsequently, a number of manufacturers and universities have adopted the MUSCLE PC/SC stack (called PC/SC Lite), making it available for numerous platforms, free of charge with source code included. Currently, PC/SC Lite implementations can be found on Linux, Solaris, Mac OS X, BSD, and HP-UX. The initial PC/SC Lite implementation went through many iterations while determining the best way to provide smart card services to multiple applications, cope with platform dependencies, and continue to follow the PC/SC behavior guidelines. Early versions of PC/SC Lite envisioned smart card resource managers as abstract objects in a network environment where smart card services could be accessed either in a local or a remote fashion. In Unix environments, services such as telnet, ftp, and others would require authentication for these services. Because the card and reader would generally be located in a different location than the authentication requesting host, a need for virtualization of smart card services was envisioned. A novel idea it was, yet it provided many security concerns. However, perhaps the cut was too low level. Consider the risks involved in this approach:

  • Because raw application protocol data units (APDUs) could be sent anonymously to the smart card, an anonymous user could connect to a user's card remotely and call invalid VERIFY KEY commands blocking the user's key or PIN on the card. This would create quite a problematic denial of service attack.

  • Consider an application that connects in shared mode, verifies a PIN, and waits for user input. Meanwhile a remote user connects and has complete control of the card because PIN authentication has already been met. Perhaps the remote user has just briefly stolen your identity and you never knew it.

Several measures could be taken to avoid these scenarios, including authenticating the remote host to the local machine. While attractive in theory, the mechanism is undesireable because it tends to position identity authentication outside the realm of the smart card where the security of the platforms can be questioned.

Perhaps the best way to provide remote services to a smart card is to make the cut at a higher level. Above the card or crypto service provider for the card is aware of the card's capabilities and its ability to tolerate invalid PINs. By providing a limited set of functions to the remote application, you invalidate many scenarios where remote users can engage in probing attacks.

PC/SC Lite Implementation

To develop a smart card stack on various computer O/S platforms, a local smart card resource manager was needed, and support for remote services would need to be a layered service on top of this, if desired (perhaps through ssh or gss-api). Users could choose to accept the security risk of a remote service provider instead of having it by default. To provide a cross-platform means of interprocess communication, POSIX-style domain sockets were chosen as the best means of providing this service. Sockets have novel ways of providing a queuing mechanism for application ordering. Also, with their tight kernel integration, the resource manager can detect when a client dies from a segmentation violation or even when it exits normally. This is important because a client could connect to the resource manager in shared mode, validate a PIN, and then segmentation fault or exit without closing its sessions. It may be possible for another application to connect to the card and use this validated PIN for access to other card services. With client exit detection, PC/SC Lite has a mechanism in which it will automatically reset all cards associated with a dead client immediately to deny the possibility of an inherent security risk associated with open sessions.

PC/SC Lite is written with most of the well-known GNU tools allowing it to build on most any platform where GNU tools are present. It was written in ANSI C calling conventions with little interaction with external libraries. Its core service pcscd is a daemon that runs in a privileged mode so that it can access hardware responsible for being an arbiter to multiple

  • applications

  • readers with multiple slots

  • users

  • smart card types

The pcscd daemon can be started from the command-line mode or it can be instantiated to run on startup as a background process. Its sole purpose is to make decisions. When instantiated, it follows these steps:

  1. allocates memory for readers and public share

  2. gathers information about static readers, such as serial readers

  3. probes the hotplug plug-in mechanism for hot pluggable readers, such as USB or PCMCIA devices

  4. sets up its common channel for applications to make initial requests

  5. listens for common channel requests

Applications connect to pcscd by linking with a small client-side library called libpcsclite.so (on Macintosh platforms by adding PCSC.framework in Project Builder). Their initial call to SCardEstablishContext will send a packet to the common channel and the server will set up a unique port for the application. This will initiate a communication channel that the application holds privately with the resource manager. Each application holds its own communication channel that the resource manager blocks on in a bit mask using a select system call. Each call to the resource manager is serialized and then executed, with the result being passed to the application. PC/SC Lite currently supports up to 16 simultaneous readers with up to 4 slots per reader. It can handle 16 applications and even manage to track the insertion and removal of new devices.

Linux Implementation

Since Unix evolved over many years, different services arose from the platform to allow functionality either locally or remotely. Most of these services would utilize the standard /etc/passwd file and perform an authentication based on passwords. Many corporations struggled with the fact that each Unix system might require different passwords for users and a particular user might need access to many Unix workstations. Some services such as NIS were introduced to help alleviate this lack of single sign-on by mapping the /etc/passwd file from a network file share. Recently, single sign-on has been introduced in Unix systems to allow pluggable authentication through the use of Pluggable Authentication Modules (PAM). PAM allows the system administrator to choose its means of authentication for a particular service. Administrators may choose to “stack” PAM modules so that multiple forms of authentication must be met in order for successful login. In order for PAM to be successful, application writers must use the PAM interface to write software to in order to accommodate this. Currently, PAM has been adopted for most Unix services including login, ftp, telnet, ssh, chfn, and xdm. Each application can have its own authentication method. An administrator may choose that login require strong authentication and ftp not as strong. In this scenario, it would be possible to have login use Kerberos for authentication and passwords for the ftp daemon. Smart card authentication can be provided through PAM in the same mechanism. The following shows an example PAM module, which for simplicity, looks for the presence of a smart card:

#define PAM_SM_SESSION

#include <security/pam_modules.h>
#include <winscard.h>

PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                                int argc, const char **argv) {
  LONG rv;
  SCARDCONTEXT hContext;
  SCARDHANDLE hCard;
  SCARD_READERSTATE_A rgReaderStates;

  pam_get_user( pamh, &sUser, "Login: " );

  /* Connect to the smartcard subsystem */
    SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, &hContext);

  mszGroups = 0;
  SCardListReaders( hContext, mszGroups, 0, &dwReaders );
  mszReaders = (char *)malloc(sizeof(char)*dwReaders);
  SCardListReaders( hContext, mszGroups, mszReaders, &dwReaders );

  rgReaderStates.szReader            = mszReaders;
  rgReaderStates.dwCurrentState  = SCARD_STATE_EMPTY;

  /* Wait for a card to be inserted */
  printf("Please insert your smartcard - ");
  fflush(stdout);
  SCardGetStatusChange( hContext, INFINITE, &rgReaderStates, 1 );

  rv = SCardReleaseContext( hContext );

  return PAM_SUCCESS;
}

The following is an example configuration file for using the PAM module with the login service:

auth       required      /lib/security/pam_smartcard.so

...

Many Unix applications could make use of the smart card for authentication purposes. The GSS API is used in many instances to authenticate applications that reside on different hosts. Kerberos is currently used as a means of authentication in hundreds of institutions, schools, and businesses. PAM is used on most Unix systems today as an abstract means of authentication. Smart cards will creep into these infrastructures and play a vast role in the Unix environment as the middleware and drivers mature and become available for these platforms.

Mac OS Implementation

In 2000, Apple Computer joined the PC/SC Workgroup as a core member and adopted the PC/SC Lite framework for its core smart card services. Apple's PC/SC stack would exist in its revolutionary Unix-based operating system, Mac OS X. It was necessary to provide smart card services in a way that would benefit the average Macintosh user. To do this, Apple chose widely adopted standards to support in its operating system, including CCID-based readers and Java Card–compliant cards. OS X consists of a security framework called CDSA™, which was developed by Intel's Architecture Labs (IAL) in the mid 1990s. CDSA provides a high-level API for most security services, including certificate management, cryptographic service providers, trust policies managers, authorization policies, directory service management, and more. It was released into the open source to provide a totally open security middleware for the development of security-aware applications. By using a pluggable architecture, an application can request security services in an abstract manner and not have to worry about specific technologies. Apple's core security-aware applications make use of the high-level CDSA API, allowing vendors to plug support for their devices without modifying existing applications. One notable example is the Apple Keychain. The Keychain is an application that stores passwords from programs to ease the memories of the user. Because most users are cluttered with remembering many passwords, these are stored encrypted with a master password. By adding smart card support to the CDSA cryptographic service provider (CSP), these applications and new applications can make use of the smart card for cryptographic services. Apple also has a means of pluggable authentication to allow a user to write a pluggable module, in which a smart card can be used to authenticate to system services available under Mac OS X.

Drivers for Mac OS X follow the same guidelines, as do drivers for other Unix platforms. Because the Macintosh has deprecated the serial port for quite some time, hot pluggable USB readers are the standard reader for the Macintosh platform. Because the drivers are written in user space and not as kernel modules, it is possible to abstract much of the USB communication and have one driver code base that works on multiple platforms. The bundle architecture allows you to provide separate subdirectories for each driver library and distribute one package that works on multiple platforms for USB readers.

SSP

Above the communication layer in libpcsclite exists the application provider interface, which applications call to use the functionality of the smart card resource manager. This API, which also exists on Windows-based platforms, provides the lowest level application usable set of functions in the PC/SC stack.

Applications or service providers use the following API:

long SCardEstablishContext(    unsigned long  dwScope,
                const void *pvReserved1,
                const void *pvReserved2,
                long *phContext );

  long SCardReleaseContext(       long hContext );

  long SCardSetTimeout(              long hContext,
                          unsigned long dwTimeout );

  long SCardConnect(                   long hContext,
                 const char  *szReader,
                 unsigned long  dwShareMode,
                 unsigned long  dwPreferredProtocols,
                 long *phCard,
                 unsigned long *pdwActiveProtocol );

  long SCardReconnect(               long hCard,
                                  unsigned long dwShareMode,
                 unsigned long dwPreferredProtocols,
                 unsigned long dwInitialization,
                 unsigned long *pdwActiveProtocol );

  long SCardDisconnect(              long hCard,
                 unsigned long dwDisposition );

  long SCardBeginTransaction(    long hCard );

  long SCardEndTransaction(       long hCard,
                                   unsigned long dwDisposition);

  long SCardCancelTransaction(   long hCard );



  long SCardStatus(                     long hCard,
                char *mszReaderNames,
                unsigned long *pcchReaderLen,
                unsigned long *pdwState,
                unsigned long *pdwProtocol,
                unsigned char *pbAtr,
                unsigned long *pcbAtrLen );

  long SCardGetStatusChange(    long hContext,
                                 unsigned long dwTimeout,
                                 LPSCARD_READERSTATE_A rgReaderStates,
                                  unsigned long cReaders );

  long SCardControl(                    long hCard,
                 const unsigned char *pbSendBuffer,
                 unsigned long        cbSendLength,
                 unsigned char       *pbRecvBuffer,
                 unsigned long       *pcbRecvLength );

  long SCardTransmit(                   long hCard,
                  LPCSCARD_IO_REQUEST  pioSendPci,
                  const unsigned char *pbSendBuffer,
                  unsigned long        cbSendLength,
                  LPSCARD_IO_REQUEST   pioRecvPci,
                  unsigned char       *pbRecvBuffer,
                  unsigned long       *pcbRecvLength );

  long SCardListReaderGroups(   long hContext,
                                                       char  *mszGroups,
                                    unsigned long *pcchGroups );

  long SCardListReaders(               long hContext,
                 const char *mszGroups,
                 char *mszReaders,
                 unsigned long *pcchReaders);
  long SCardCancel(                     long hContext );

This level of abstraction provides a clean API to communicate to a card without knowing anything about the reader. It provides a means of multiple application communication to a particular card by providing sharing and locking mechanisms so that each application can hold a transaction to a particular card for a period of time.

Reader Device Driver

Drivers for Unix follow a simple user space API. User space drivers are easy to port, easy to debug, and have equal security as kernel drivers when written properly. PC/SC Lite became popular because driver writing was a quick and easy procedure even if the programmer had no driver writing experience whatsoever. IFD Handler developer's kits are provided on the MUSCLE site with skeleton code to allow quick addition of support for other readers. All drivers can be easily written using a few functions. The following is a list of the functions used for PC/SC Lite drivers:

RESPONSECODE IFDHCreateChannel (  DWORD, DWORD );
  RESPONSECODE IFDHCloseChannel (   DWORD );
  RESPONSECODE IFDHGetCapabilities ( DWORD, DWORD, PDWORD,
                                                   PUCHAR );
  RESPONSECODE IFDHSetCapabilities (  DWORD, DWORD, DWORD,
                    PUCHAR );
  RESPONSECODE IFDHSetProtocolParameters ( DWORD, DWORD, UCHAR,
                                                      UCHAR, UCHAR, UCHAR );
  RESPONSECODE IFDHPowerICC (         DWORD, DWORD, PUCHAR, PDWORD );
  RESPONSECODE IFDHTransmitToICC ( DWORD, SCARD_IO_HEADER, PUCHAR,
                                                DWORD, PUCHAR, PDWORD,
                                                PSCARD_IO_HEADER );
  RESPONSECODE IFDHControl (              DWORD, PUCHAR, DWORD,
                             PUCHAR, PDWORD );
  RESPONSECODE IFDHICCPresence(      DWORD );

These functions provide a simple, yet robust API for establishing communication to a smart card or cryptographic device. The device may even not exist as a smart card, yet it could adhere to this API and be made available in the PC/SC framework. It is important that non–smart card functionality be provided by which this API provides the IFDHControl function. This function accepts a string of bytes that the driver interprets as commands. Drivers adhere to the MCT specifications for extended services such as LCD and PIN pads.

In most Unix platforms, plug-and-play exists only for PCI, USB, and PCMCIA devices. On Windows, it is possible to have a plug-and-play serial device. Unix provides no means of plug-and-play for serial devices and, therefore, pcscd does not allow hotplugging of serial devices. These “static” devices must be specified in a configuration file called /etc/reader.conf. A typical configuration file might look like the following:

# reader.conf by David Corcoran

FRIENDLYNAME     "Generic Reader"
DEVICENAME           GEN_SMART_RDR
LIBPATH                     /usr/lib/readers/libgen_ifd.so
CHANNELID              0x0103F8

FRIENDLYNAME is the name of the reader, DEVICENAME is reserved for future use, LIBPATH is the path to the driver, and CHANNELID specifies the channel. In this example, COM1 is stated “3F8”. In many instances, this mechanism for identifying readers can become cumbersome, especially if your reader is a hotpluggable reader such as a USB reader. In this case, the driver is placed in a drop folder, typically /usr/local/pcsc/drivers/. This folder includes drivers for hotpluggable readers and they are in “bundle” form. The NSBundle came from Apple's OS X as a means of providing a driver and obtaining information in an abstract manner.

The pcscd daemon uses a bundle parsing library to provide functions to bundles that would be in the general OS X distribution to provide cross-platform support for bundles. Hotpluggable drivers in the form of a bundle contain a file Info.plist, which contains XML information about the driver itself, including its name, library path, and other parameters. A typical short Info.plist file might look like the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
        <key>CFBundleDevelopmentRegion</key>
        <string>English</string>
        <key>CFBundleExecutable</key>
        <string>slbReflexUSB</string>

        <key>ifdVendorID</key>
        <string>0x04E6</string>
        <key>ifdProductID</key>
        <string>0x2004</string>
        <key>ifdFriendlyName</key>
        <string>SLB Reflex USB</string>

        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <string>0.0.1d1</string>
       <key>CSResourcesFileMapped</key>
        <true/>
</dict>
</plist>

The pcscd daemon looks at the specified vendor and product IDs in the bundle and scans for the devices on the bus to determine whether they need to be loaded or unloaded. The bundle style also allows you to distribute multiple OS drivers in the same package just by changing the Info.plist. Supporting OEM devices is as simple as changing the Info.plist. As you can see from the preceding code, there are four items necessary to inform pcscd of the reader: ifdVendorID, ifdProductID, ifdFriendlyName, and CFBundleExecutable.

CryptoAPI

A major use of smart cards in any general computer system, as has been intimated throughout the course of this book, is the provision of cryptographic services in support of general security infrastructures. In particular, the smart card is the best place to store a private key (of a public/private key pair) through which an individual's identity is established in a public key infrastructure. Also, the smart card, as a secure computing platform, is the best place to actually perform the digital signature operation that makes use of the private key. Today, two major cryptographic modules exist to provide application-level cryptographic services:

  • CryptoAPI on Windows platforms

  • PKCS-11 on Windows and other platforms

Both of these software packages can provide cryptographic services independent of any use of smart cards. However, both can also allow the use of smart cards as personalized security tokens within these systems. Let's first look at the CryptoAPI (or CAPI) architecture that is found as an integral part of the Windows systems.

Architecture

There are two levels to the CAPI architecture. The CryptoAPI itself, which offers an API comprised of a number of functions that applications can use to perform cryptographic operations. These functions allow for bulk encryption of information as well as for computation of digital signatures on bulk data structures. Many general Windows applications such as Web browsers and email readers make use of CAPI services for security. Figure 7.9 illustrates the general CAPI architecture.

CryptoAPI architecture.

Figure 7.9. CryptoAPI architecture.

API

The CAPI is a general-purpose API through which applications can gain access to cryptographic services. Just as with other standardized APIs that we've considered, this one seeks to isolate the application from any of the differences that can occur within the actual implementation of the API. In the case of cryptographic services, there are a number of ways that system services can vary.

First of all, cryptography is often subject to export restrictions in a number of countries. In some instances, cryptography can't be used at all while in others the quality of the cryptographic operaion is limited. In these instances, it is useful to be able to support what we call “strong cryptography” in some instances while supporting “weak” or “exportable cryptography” in other instances. In both cases, we prefer that the application not have to know about the differences. The CAPI architecture allows us to achieve this.

Within the CAPI architecture is a layer labeled the Cryptographic Services Provider or CSP layer. The CAPI itself can actually go to any CSP for its actual cryptographic operations. So, by providing a variety of CSPs, one can wash out the differences (in cryptographic operations) from the viewpoint of the application. This mechanism allows us to use a number of different smart cards for cryptographic operations as well.

As we've learned in previous chapters, smart cards are good, secure platforms on which to store keys and do limited encryption and decryption operations. Of course, we want to be able to use smart cards from a variety of vendors. We can do this within the CAPI architecture by having a different CSP for each smart card we want to use.

CSP

The CAPI model allows for a variety of token devices to be integrated with CAPI-based applications. As you'll note in Figure 7.9, the CAPI architecture allows for a variety of CSPs to be integrated into the CAPI package. Each of these CSPs can support a single token (smart card). When an application makes a reference to the CAPI interface for some cryptographic operation, if that operation can be performed via some token, the CAPI module makes a further reference to the CSP interface for a specific token. The result is that applications can be built that make use of a token, but that token can actually be provided by a number of different vendors, without requiring any change on the part of the application.

PKCS-11

An alternative cryptographic module exists in the form of PKCS-11. Above the service to plug in a smart card or cryptographic token resides a layer for abstracting simple cryptographic operations into methods of use with public key systems. In the early 1990s, RSA Laboratories announced a new specification targeted at cryptographic devices known as PKCS-11, or Cryptoki. This standardized API gives cryptographic token abstraction, service sharing, and management of keys and data while treating the device like an object. Since the introduction of PKCS-11, it has become a widely accepted cryptographic plug-in interface and has been implemented in applications and frameworks such as Netscape and CDSA, as well as many others. It also is responsible for event notification, such as if a card or token is removed from its slot. It must convey a device's capabilities to the above application or framework so that it is known whether the currently selected device supports a particular cryptographic algorithm. It must manage PIN numbers or CHVs that are commonly used to link a key to a person with “something he or she knows.” It offers cryptographic services such as digital signing, hashing, encryption/decryption, signature verification, key generation, and certification management.

Architecture

Figure 7.10 illustrates the general architecture of the PKCS-11 model. As with the CAPI model, many different applications can make use of the PKCS-11 API and therefore be insulated from differences in many aspects of how cryptographic operations are actually performed. A single PKCS-11 module can support many smart card readers and many different smart cards.

PKCS-11 architecture.

Figure 7.10. PKCS-11 architecture.

In Figure 7.10, two slightly different PKCS-11 stacks are represented. In the first, on the left of the figure, a PKCS-11 module is built on top of a standard PC/SC smart card stack. The top of the smart card stack in this case is the SSP for the specific smart card being used. By providing different SSPs, each of which actually presents the same API to the PKCS-11 package, a variety of smart cards can be used. Notice in this case that the SSP API is not a standard specification. Thus, a single PKCS-11 module provider might adopt a homegrown SSP API, but a different smart card vendor would have to gain access to that API definition if a new smart card was to be introduced. The point is that PKCS-11 doesn't have quite the same API layer definition that the CSP API represents in the CAPI arena. This is, it didn't until the definition (relatively recently) of the PKCS #15 API.

PKCS #15

PKCS #15 is a specification of a general storage facility for the objects used within PKCS #11. This storage facility can simply be a software implementation on the PC, much like the PKCS #11 module is. However, a PKCS #15 module can also make use of a token, such as a smart card, for storage of the PKCS #11 objects. So, cryptographic keys, for example, can be stored on a smart card and access a standard PKCS #15 API. This makes it fairly straightforward to build a general PKCS #11 module that can, in turn, make use of a variety of different smart cards for key storage.

The parallel between PKCS #15 and the CSP is not quite exact in that through the CSP interface one can also access cryptographic operations on the smart card.

Standardizing on a Smart Card Application (Applet)

An alternative to PC side APIs is to define a portable application that provides cryptographic services. Such an applet could be written for Java Card smart cards and then loaded onto Java Card-compliant smart cards from various vendors. If an SSP is written to talk to this applet, then a true card edge interface for smart card support for cryptographic operations should be achieved. The MUSCLE group has moved in this direction by releasing an open, card-independent specification and implementation of a Java Card applet for easy use of a smart card called the MuscleCard Cryptographic Card Edge Interface (CCEI). The idea was to provide most of the user's needs and create an applet that could be widely deployed by following the Java Card specification, thus allowing an application provider to use any (Java Card-compliant) card that follows this standard.

The applet is split into four major sections:

  • key management and use

  • PIN management and use

  • object management and use

  • utility functions

Key management and use includes all functions that would make use of cryptographic keys. These functions include, Import, Export, GenerateKeyPair, Crypt, and ExtAuthenticate. RSA, DSA, DES, and 3DES are currently supported.

PIN management and use includes all functions that would make use of PIN or cardholder verification (CHV). These functions include CreatePIN, ChangePIN, VerifyPIN, and UnblockPIN. Eight PIN numbers are currently supported on the card.

Object management and use includes all functions that would make use of data objects to be stored or retrieved on the card. These functions include CreateObject, DeleteObject, ReadObject, and WriteObject.

Utility functions include all functions that convey information or provide utility to the calling application. These functions include ListKeys, ListPINs, ListObjects, GetRandom, and LogoutAll.

STIP–Small Terminal Interoperability Platform

Another significant effort to provide a standard smart card stack comes for a group creating the STIP specification. STIP (small terminal interoperability platform) is aimed at small terminal systems, and is written in Java. The STIP architecture is illustrated in Figure 7.11.

STIP architecture.

Figure 7.11. STIP architecture.

STIP assumes a general Java environment for a terminal. It allows various applications to be written and loaded onto the terminal in a standard fashion. These applications will be portable across a variety of hardware platforms that support STIP. The STIP APIs and various hardware elements connected to the terminal can be utilized by the terminal.

Summary

In this chapter, we've considered some aspects of smart card middleware on a variety of computer platforms. We've concentrated on the PC/SC architecture as it has been applied to both Windows platforms as well as a variety of other general computer platforms. This has provided a means of making applications independent of specific smart card readers and, to a large extent, provided for the prospect of obtaining smart cards (for a particular application) from a variety of vendors. We've looked at the use of the PC/SC specifications to build smart card stacks on many PC configurations besides Windows. In addition, we've looked at the use of smart cards to support cryptographic services in the context of a PC/SC-based smart card stack.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.144.69