Previous section.

Common Security: CDSA and CSSM, Version 2 (with corrigenda)
Copyright © 2000 The Open Group

Add-In Module Administration

Besides security services, there are several additional steps that must be performed by the module developer in order to insure access to the module via CSSM.

To insure system integrity, a module developer must create a set of digital credentials to be verified by CSSM when the module is loaded.

The module developer must create an installation program to register the module's identity, capabilities, and signed manifest credentials with the Module Directory Services (MDS).

Finally, the module developer must ensure that the appropriate sequence of component verification and module initialization steps occur prior to dynamic binding of the module with CSSM.

Manufacturing an Add-In Module

A complete set of credentials must be created for each CSSM add-in security service module as part of the module manufacturing process. These credentials are required by CSSM in order to maintain the integrity of the CDSA system. A full set of credentials is shown in Credentials of an Add-In Service Module and Certificate Chain for an Add-In Service Module. The set includes:

These three objects form a single set of credentials. The credentials are stored as an attribute of the module. All module attributes are stored in relations managed by MDS. The module's manifest is stored as a binary blob representation of the manifest file in the MDS relation.


Figure: Credentials of an Add-In Service Module

The module's certificate is the leaf in one or more certificate chains. Each chain is rooted at one of a small number of known, trusted public keys. A single chain is shown in Certificate Chain for an Add-In Service Module. A CSSM vendor issues a certificate to the module vendor, signed with the private key of the CSSM vendor's certificate. The module vendor issues a certificate for each of its products, signing the product certificate with the module vendor's certificate.


Figure: Certificate Chain for an Add-In Service Module

The manifest forms a complete description of an add-in module. A manifest includes a manifest section for each object code file that is part of a module's implementation. Each manifest section contains:

The object code files are standard OS-managed entities. Object files do not embed their digital signatures, instead, signatures are stored in a manifest separate from, but related to, the object files.

A digest of each manifest section is then computed and stored in the signature info file.

The signature file contains the PKCS#7 signature computed over the signature info file.

This set of credentials must be manufactured when the module is manufactured. Assuming a module manufacturer already has a certificate from a CSSM manufacturer, the module manufacturing process proceeds as follows:

  1. Generate an X.509 product certificate for the module and sign it with the manufacturer's certificate.

  2. Create a SHA-1 digest of each implementation component (object code file) used in the module.

  3. Build a manifest which describes the module by referencing all object code files and digests embedded in those files.

  4. Build a signature info file which contains a SHA-1 digest of each manifest section.

  5. Sign a SHA-1 digest of the signature info file using the private key of the product's certificate.

  6. Create a PKCS #7 signature containing the signature info file digest, the product certificate and the signature.

  7. Place the PKCS #7 signature in a signature file.

It is of the utmost importance that the object code files and the manifest be signed using the private key associated with the product certificate. This tightly binds the identity in the certificate with "what the module is" (that is, the object code files themselves) and with "what the module claims it is."

Authenticating to Multiple CSSM Vendors

A single add-in module can authenticate with and attach to different instances of CSSM, even if these instances require add-in module credentials based on difference roots of trust. Multiple CSSM Vendors Authenticating Same Application. shows a complete set of credentials for an add-in module that can authenticate with a CSSM that accepts any one of three roots of trust. The credentials include three certificate chains. Each chain has a distinct root, and all chains sign the product. All three certificate chains are included in the credentials for this add-in module. When CSSM #1 attempts to verify the add-in module's credential, a verified certificate chain will be constructed from the add-in module's leaf certificate to the root certificate containing either public key PK2 or public key PK3, which are recognized as points of trust by CSSM #1. Hence the add-in module's credentials will be successfully verified. CSSM #2 would verify the add-in module using public key PK5.

Figure: Signature File for Add-In Module with Authentication Capability

Obtaining an Add-In Module Manufacturing Certificate

Every add-in module must have an associated set of credentials, including a product certificate signed by the module manufacturer's certificate. If the module must be fully authenticated by the CSSM, then the module manufacturer must obtain a manufacturing certificate from each CSSM vendor it wishes to work with. The specific procedure for obtaining a manufacturing certificate depends on the CSSM vendor. The manufacturing certificate must be signed with the CSSM vendor's certificate and returned to the add-in module vendor.

Issuing an Add-In Module Product Certificate

A product certificate should be issued for each distinct product. The add-in module vendor defines what constitutes a distinct product. The product certificate must be directly or indirectly signed by the add-in module vendor's manufacturing certificate. Issuing a product certificate incorporates some of the processes of a Certificate Authority.

Manufacturing Add-In Modules

Manufacturing an add-in module is a three-step process:

  1. Incorporating integrity-checking facilities and roots of trust in the product software

  2. Compiling the software components of the product

  3. Generating integrity credentials for the add-in module product

An add-in module that performs self-check and/or authenticates CSSM during module attach must:

The root of trust for self-check is the public key of the product certificate. The root of trust for authenticating a CSSM is the public root key of the CSSM vendor. Roots of trust can be presented as certificates or as keys. The add-in module should include the roots for all CSSM vendors that it trusts. This knowledge can be embedded as part of the module manufacturing process. Once the roots of trust are known, load-time integrity checking can be performed.

CSSM invokes the module's CSSM_SPI_ModuleLoad() function to initiate the module's integrity check of CSSM. Although CSSM cannot determine that the add-in module has performed self-check and verified CSSM's credentials it is highly recommended that modules perform these checks at load-time and periodically during execution based on elapsed time or usage. Failure to perform this verification during module load processing compromises the integrity of the entire runtime environment.

After the roots of trust have been incorporated into the software component of the product and all product software components have been compiled and linked, the service module credentials should be created. Signed manifest credentials consist of three sub-blocks:

The manifest block contains:

After the manifest block is created, the signer information block is created. The signer's information file must contain:

Finally the signature block is created. The signature block must contain:

The signing operation must be performed using the private key associated with the product certificate.

The signed manifest credentials must be included in a module-specific record in the MDS Common relation. The record(s) is created by the module's installation program.

Installing a Service Module

Before an application can use a module, the module's name, location and description must be registered by an installation program. The installation program creates one or more records in one or more MDS relations. To insert new records, the installation program must have write-access to the MDS CDSA Directory database. MDS controls write-access to all MDS databases. Write-access is granted only to signed, authorized applications.

The MDS CDSA Directory database contains numerous relations storing descriptions of CSSM, EMMs, and all types of CDSA service provider modules. Every service module must have at least one record in the MDS Common relation. This relation stores the general attributes applicable to all module types. These attributes include:

The GUID is a structure used to differentiate between library modules. It is the primary database key for locating the module's records stored in MDS. The sub-components of a GUID are discussed in more detail below.

The logical name is a string chosen by the module developer to describe the module. The module location is determined at installation time. The installation program must set this value so the module can be located when CSSM attempts to load the service module is response to a application's CSSM_ModuleLoad() request. More detailed description of the module and its services are stored in other MDS relations. These options are described below.

Global Unique Identifiers (GUIDs)

Each module must have a globally-unique identifier (GUID) that the CSSM, applications, and the module itself use to uniquely identify a given module. The GUID is used as the primary database key to locate module information in MDS. When loading the library, the application uses the GUID to identify the requested module.

The Module Description

At install time, the installation program must register (advertise) its availability on the system. This is accomplished by adding one or more records to the MDS Common relation and optionally adding module-specific records to selected relations in the MDS CDSA Directory database. MDS defines relations based on security service types.

Service modules providing cryptographic services should consider inserting records in the following MDS relations:

Service modules providing data storage library services should consider inserting records in the following MDS relations:

Service modules providing certificate library services should consider inserting records in the following MDS relations:

Service modules providing trust policy services should consider inserting records in the following MDS relations:

Multi-service modules should add records in all application categories of security services.

New elective security services areas must define new MDS relations to store appropriate description for those new categories of service. This requires schema modification and privileged access to the MDS database. See the section on installing elective module managers in this specification for the definition of the required procedures.

All records inserted in the MDS database are available to applications and other CDSA components via MDS queries. Consult the MDS description and schema definitions contained in this specification when developing an installation program for a service module.

Attaching a Service Module

Runtime Life Cycle of the Module

Applications dynamically select the service modules that will provide security services to the application. Selection and session establishment is a multiple step process. When the module's services are no longer required, de-selection is also a multi-step process. The runtime life cycle of the service module and the sequence of function calls required among applications, CSSM and the service module are as follows:

  1. An application invokes CSSM_ModuleLoad() - after invoking CSSM_Init() and before invoking CSSM_ModuleAttach(). The function CSSM_ModuleLoad() initializes the add-in service module. Initialization includes

    The application may provide an event handler function to receive notification of insert, remove and fault events.

  2. CSSM verifies the add-in service module's manifest credentials. If the credentials and the module code are successfully verified, CSSM invokes CSSM_SPI_ModuleLoad() to complete the module initialization process. CSSM_SPI_ModuleLoad() must be implemented by the service provider module. In response to this function, the service provider module must

    The CSSM calls CSSM_SPI_ModuleLoad() each time the application invokes the CSSM_ModuleLoad() call.

  3. The application invokes CSSM_ModuleAttach() to complete selection of the module.

  4. CSSM carries out the attach process by calling the module interface CSSM_SPI_ModuleAttach().

    The service module should also:

    The CSSM_SPI_ModuleAttach() function is called each time an application invokes the CSSM_ModuleAttach() call.

    The function table is returned to the CSSM for each attach handle. The service provider may vary the contents of the table based on the application's exemptions (if any).

  5. When the application no longer requires the module's services, the application invokes CSSM_ModuleDetach(). This closes the session and voids the attach handle associated with that session.

  6. CSSM notifies the service provider modules of the application's detach request by invoking the CSSM_SPI_ModuleDetach() function. This SPI is invoked once for each application call to CSSM_ModuleDetach(). In response to this function call, the service provider should clean-up any state information associated with the detaching session.

  7. The application invokes CSSM_ModuleUnload() to deregister the application callback functions and to release all sessions associated with target service provider module.

  8. In response, CSSM invokes CSSM_SPI_ModuleUnload(). The service module must implement this function. The CSSM_SPI_ModuleLoad() function will be called each time the application invokes the CSSM_ModuleUnload() call. When an equal number of CSSM_SPI_ModuleLoad() and CSSM_SPI_ModuleUnload() calls have been made, the function should disable events and deregister the CSSM event-notification function. The add-in service module may perform cleanup operations, reversing the initialization performed in CSSM_SPI_ModuleLoad().

Bilateral Authentication

On ModuleLoad, CSSM and the module verify their own and each other's credentials by following CSSM's bilateral authentication protocol. These practices of self-checking and cross-checking by other parties increases the level of tamper detection provided by CDSA.

The basic steps in bilateral authentication during module load are defined as follows:

  1. CSSM performs a self integrity check

  2. CSSM performs an integrity check of the attaching module

  3. CSSM verifies secure linkage by checking that the initiation point is within the verified module

  4. CSSM invokes the add-in module

  5. The add-in module performs a self integrity check

  6. The add-in module performs an integrity check of CSSM

  7. The add-in module verifies secure linkage by checking that the function call originated from the verified CSSM

The purpose of the secure linkage check is to verify that the object code just verified is either the code you are about to invoke or the code that invoked you.

In the event that a module's manifest describes more than one module, the module's GUID must be present in the manifest section. The GUID should be presented as a tag:value pair. The tag is "CDSA_GUID" and the value should be a string representation of the GUID. This allows the authenticating parties to correctly identify which module is of current concern. The verification of modules referred to by manifest sections other than the currently relevant manifest section is not necessary for bilateral authentication.

An example of a module GUID representation in a manifest is as follows:


CDSA_GUID: {01234567-9abc-def0-1234-56789abcdef0}

There should be a "CDSA_MODULE" tag in the manifest of a CSSM. The value of this tag should be "CSSM" so that other modules can verify that the calling module is a CSSM. EMMs should have the CDSA_MODULE tag with a value of "EMM" so entities (such as CSSM and addins) may verify that the module is an EMM. Other optional values for CDSA_MODULE tag are "APP" and "ADDIN" in the respective manifests.

Memory Management Upcalls

All memory allocation and de-allocation for data passed between the application and a module via CSSM is ultimately the responsibility of the calling application. Since a module needs to allocate memory to return data to the application, the application must provide the module with a means of allocating memory that the application has the ability to free. It does this by providing the module with memory management upcalls as an input parameter to CSSM_SPI_ModuleAttach().

Memory management upcalls are pointers to the memory management functions used by CSSM. If needed, the call will be routed to the calling application. They are provided to a module via CSSM as a structure of function pointers. The functions will be the equivalents of malloc, free, calloc, and re-alloc, and will be expected to have the same behavior as those functions. The function parameters will consist of the normal parameters for that function. The function return values should be interpreted in the standard manner. A module is responsible for making the memory management functions available to all of its internal functions.

Modules Control Access to Objects

Service provider modules manage objects that are manipulated through the service provider's APIs. Each service provider can control access to these objects on a per request basis according to a policy enforced by the provider. Most of the access-controlled objects are persistent, but they can exist only for the duration of the current application execution. Examples include:

A service provider must make an access control decision when faced with a request of the form "I am subject S. Do operation X for me." The decision requires the service provider to answer two questions:

The first question is answered by authentication. The second question is answered by authorization.

Authentication as Part of Access Control

There are various forms of authentication. Traditionally, the term is applied to authentication of the human user. A human is often authenticated by something he or she knows, such as a passphrase, a PIN, etc. More secure authentication involves multiple factors:

It is also possible to authenticate an entity using public cryptography and digital certificates. The entity holding a keypair can be a hardware device or instance of some software. The device or the software acts on behalf of a human user. Each entity is identified by a public signature key. Authentication is performed by challenging the entity to create a digital signature using the private key. The signature can be verified and the entity is authenticated. The digital certificate and the digital signature are credentials presented by the entity for verification in the authentication process.

Each service provider defines a policy regarding the type and number of authentication credentials accepted for verification by the service module. The credentials can be valid for some fixed period of time or can be valid indefinitely, until rescinded by an appropriate revocation mechanism.

CDSA defines a general form of access credential a caller can present to service providers when operating on objects, whose access is controlled by the service provider. A credential set consists of:

If the service provider caches authentication and authorization state information for a session, a caller may not be required to present any certificates or samples for subsequent accesses. Typically at least one sample is required to authenticate a caller and to verify the caller's authorization to perform a CDSA operation.

The general credential structure is used as an input parameter to functions in various categories of security services. A caller can provide samples through the access credentials structure in one of several modes or forms:

The service provider uses credentials to answer the authentication question.

Authorization as Part of Access Control

Once any necessary authentication samples have been gathered, authorization can proceed. Just providing a password or biometric sample does not imply that the user providing the sample should get the access he or she is requesting.

An authorization decision is based on an authorization policy. In CDSA, an authorization policy is expressed in a structure called an Access Control List (ACL). An ACL is a set of ACL entries, each entry specifying a subject that is allowed to have some particular access to some resource. Traditional ACLs (from the days of early time sharing systems) identify a subject by login name. The ACLs we deal with can identify a subject by login name, but more generally, the Subject is specified by the identification templates that is used to verify the samples presented through the credentials.

The ACL associated with a resource is the basis for all access control decision over that resource. Each entry within the ACL contains:

The ACL entry does not explicitly identify the resource it protects. The service provider module must manage this association.

The basic authentication process verifies one or more samples against templates in the ACL. Each ACL entry with a verified subject yields an authorization available to that subject.

Beyond the basic process, it is possible to mark an ACL entry with the permission to delegate. The delegation happens by one or more authorization certificates. These certificates act to connect the authorization expressed in the ACL entry from the public key subject of that entry to the authorization template in the final (or only) certificate of the chain. That is, an authorization certificate acts as an extension cord from the ACL to the actual authorized subject. Delegation by certificate is an option when scaling issues mitigate against direct editing of the ACL for every change in authorized subject.

Service provider modules are responsible for managing their ACLs. When a new resource is created at least one ACL entry must be created. The implementation of ACLs is internal to the service provider module. The CDSA interface defines a CSSM_ACL_ENTRY_PROTOTYPE that is used by the caller and the service provider to exchange ACL information.

When a caller requests the creation of a new resource, the caller should present two items:

The access credentials are required if the service provider module restricts the operation of resource creation. In many situations, a service provider allows anyone to create new resources. For example, some CSPs allow anyone to create a key pair. If resource creation is controlled, then the caller must present a set of credentials for authorization. Authentication will be performed based upon the set of samples introduced through the credentials. Upon successful authentication, the resulting authorization computation determines if the caller is authorized to create new resources within a controlled resource pool or container. If so, the new resource is created.

When a resource is created, the caller also provides an initial ACL entry. This entry is used to control future access to the new resource and its associated ACL (see Resource Owner). The service provider can modify the caller-provided initial ACL entry to conform to any innate resource access policy the service provider may define. For example, a smartcard may not allow key extraction. When creating a key pair on the smartcard, a caller can not give permission to perform the CDSA operation CSSM_WrapKey. The attempt will result in an error.

Resource Owner

How a given resource controller actually records the ownership of the resource is up to the developer of that code, but the "Owner" of a resource can be thought of as being recorded in a one-entry ACL of its own. Therefore, conceptually there are two ACLs for each resource: one that can grow and shrink and give access to users to the resource, and another that always has only one entry and specifies the owner of the resource (and the resource ACL). On resource creation, the caller supplies one ACL entry. That one entry is used to initialize both the Owner entry and the resource ACL. This is to accommodate the common case in which a resource will be owned and used by the same person. In other cases, either the Owner or the ACL can be modified after creation.

Only the "Owner" is authorized to change the ACL on the resource, and only the "Owner" is authorized to change the "Owner" of the resource. Effectively, the "Owner" acts as "the ACL on the ACL" for the full lifetime of the resource. In terms of an ACL entry, it only contains the "subject" (i.e., identifies the "Owner"), and the "delegate" flag (initially set to "No delegation"). The "Authorization tag" is assumed to convey full authority to edit the ACL, and the "Validity period" is assumed to be the lifetime of the resource. There is no "Entry tag" associated with the "Owner". Note that an "Owner" may be a threshold subject; identifying many "users" who are authorized to change the ACL. Note also that "Ownership" does not convey the right to delete the resource; that right may or may not be conveyed by the ACL.

CDSA defines functions to modify an ACL during the life of the associated resource. ACL updates include:

Modifying an ACL is a controlled operation. Credentials must be presented and authenticated to prove that the caller is the "Owner".

Error Handling

When an error occurs inside a module, the function should return the error number used to describe the error.

The error numbers returned by a module should fall into one of two ranges. The first range of error numbers is pre-defined by CSSM. These are errors that are common to all modules implementing a given function. They are described in this specification in the section on data structures for core services. The second range of error numbers is used to define module-specific error codes. These module-specific error codes should be in the range of CSSM_XX_PRIVATE_ERROR to CSSM_XX_BASE_ERROR + CSSM_ERRCODE_MODULE_EXTENT, where XX stands for the service category abbreviation (CSP, TP, AC, CL, DL). A module developer is responsible for making the definition and interpretation of their module-specific error codes available to applications.

Data Structure for Add-in Modules

CSSM_SPI_ModuleEventHandler

This defines the event handler interface CSSM defines and implements to receive asynchronous notification of events of type CSSM_MODULE_EVENT from a service provider module. Example events include insertion or removal of a hardware service module, or fault detection.

This event structure is passed to the service module during CSSM_SPI_ModuleLoad. This is the single event handle the service module should use to notify CSSM of these event types for all of the attached session with the loaded module. CSSM forwards the event to the entity that invoked the corresponding CSSM_ModuleLoad() function. The handler specified in CSSM_SPI_ModuleEventHandler can be invoked multiple times in response to a single event (such as the insertion of a smartcard).


typedef CSSM_RETURN (CSSMAPI *CSSM_SPI_ModuleEventHandler) (const CSSM_GUID *ModuleGuid, void* CssmNotifyCallbackCtx, uint32 SubserviceId, CSSM_SERVICE_TYPE ServiceType, CSSM_MODULE_EVENT EventType)
Definition

ModuleGuid

The GUID of the service module raising the event.

CssmNotifyCallbackCtx

A CSSM context specified during CSSM_SPI_ModuleLoad().

SubserviceId

The subserviceId of the service module raising the event.

ServiceType

The service mask of the sub-service identified by Subservice.

EventType

The CSSM_MODULE_EVENT that has occurred.

CSSM_CONTEXT_EVENT_TYPE

This list defines event in the lifecycle of cryptographic contexts. When such an event occurs, CSSM delivers the appropriate event signal to the affected cryptographic service provider. Signals of this type are issued to the module by invoking the EventNotify interface, which the cryptographic service provider module specifies during module attach processing.

typedef enum cssm_context_event{ CSSM_CONTEXT_EVENT_CREATE = 1, CSSM_CONTEXT_EVENT_DELETE = 2, CSSM_CONTEXT_EVENT_UPDATE = 3, } CSSM_CONTEXT_EVENT;

CSSM_MODULE_FUNCS

This structure is used by add-in service modules to return function pointers for all service provider interfaces that can be invoked by CSSM. This includes interfaces to real security services and interfaces to administrative functions used by CSSM and the service provider to maintain the environment. This structure accommodates function tables for service modules implementing new elective categories of services that have not been defined yet. Many operating environments provide platform-specific support for strong type checking applied to function pointers. This specification allows for the use of such mechanisms when available. In the general case a function pointer is considered to be a value of type CSSM_PROC_ADDR.

typedef struct cssm_module_funcs { CSSM_SERVICE_TYPE ServiceType; uint32 NumberOfServiceFuncs; const CSSM_PROC_ADDR *ServiceFuncs; } CSSM_MODULE_FUNCS, *CSSM_MODULE_FUNCS_PTR;
Definition

ServiceType

A CSSM_SERVICE_TYPE value indicating the category of security services available through the function table. For known categories of service, this type is used to determine the ordering of function pointers within the function table.

NumberOfServiceFuncs

The number of function pointers for the security service functions contained in the table of ServiceFuncs.

ServiceFuncs

Memory address of the beginning of the function pointer table for the security service functions identified by ServiceType.

CSSM_UPCALLS

This structure is used by CSSM to provide service functions to add-in service modules and elective module managers. The provided functions include:

A service module or an elective module manager can invoke this service at anytime during the life cycle of an attach-session.


typedef void * (CSSMAPI *CSSM_UPCALLS_MALLOC) (CSSM_HANDLE AddInHandle, uint32 size); typedef void (CSSMAPI *CSSM_UPCALLS_FREE) (CSSM_HANDLE AddInHandle, void *memblock); typedef void * (CSSMAPI *CSSM_UPCALLS_REALLOC) (CSSM_HANDLE AddInHandle, void *memblock, uint32 size); typedef void * (CSSMAPI *CSSM_UPCALLS_CALLOC) (CSSM_HANDLE AddInHandle, uint32 num, uint32 size); typedef struct cssm_upcalls { CSSM_UPCALLS_MALLOC malloc_func; CSSM_UPCALLS_FREE free_func; CSSM_UPCALLS_REALLOC realloc_func; CSSM_UPCALLS_CALLOC calloc_func; CSSM_RETURN CSSMAPI (*CcToHandle_func) (CSSM_CC_HANDLE Cc, CSSM_MODULE_HANDLE_PTR ModuleHandle); CSSM_RETURN (CSSMAPI *GetModuleInfo_func) (CSSM_MODULE_HANDLE Module, CSSM_GUID_PTR Guid, CSSM_VERSION_PTR Version, uint32 *SubServiceId, CSSM_SERVICE_TYPE *SubServiceType, CSSM_ATTACH_FLAGS *AttachFlags, CSSM_KEY_HIERARCHY *KeyHierarchy, CSSM_API_MEMORY_FUNCS_PTR AttachedMemFuncs, CSSM_FUNC_NAME_ADDR_PTR FunctionTable, uint32 *NumFunctionTable); } CSSM_UPCALLS, *CSSM_UPCALLS_PTR;
Definition

malloc_func

The application-provided function for allocating memory in the application's memory space.

free_func

The application-provided function for freeing memory allocated in the application's memory space using malloc_func.

realloc_func

The application-provided function for re-allocating memory in the application's memory space that was previously allocated using malloc_func.

calloc_func

The application-provided function for allocating a specified number of memory units in the application's memory space.

CcToHandle

A CSSM service function returning the module attach handle associated with a cryptographic context handle.

GetModuleInfo_func

A CSSM service function for use by Elective Module Managers and service modules to obtain the state information associated with the module handle. This information is initialized when an application calls CSSM_ModuleAttach(). Returned information includes the application-specified memory management functions, callback function, and callback context associated with the module handle.

Contents Next section Index