|
Packit |
8681c6 |
# PKCS #11 openCryptoki for Linux HOWTO
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
v1 - Kristin Thomas - kristint@us.ibm.com
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
v2 - Eduardo Barretto - ebarretto@linux.vnet.ibm.com
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This HOWTO describes the implementation of the RSA Security Inc./Organization
|
|
Packit |
8681c6 |
for the Advancement of Structured Information Standards (OASIS) Public Key
|
|
Packit |
8681c6 |
Cryptographic Standard #11 (PKCS #11) cryptoki application program interface
|
|
Packit |
8681c6 |
(API) on Linux (openCryptoki). The HOWTO explains what services openCryptoki
|
|
Packit |
8681c6 |
provides and how to build and install it. Additional resources and a simple
|
|
Packit |
8681c6 |
sample program are also provided.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
## Table of contents
|
|
Packit |
8681c6 |
1. [Copyright Notice and Disclaimer](#1-copyright-notice-and-disclaimer)
|
|
Packit |
8681c6 |
2. [Introduction](#2-introduction)
|
|
Packit |
8681c6 |
3. [What is openCryptoki?](#3-what-is-opencryptoki)
|
|
Packit |
8681c6 |
4. [Architectural Overview](#4-architectural-overview)
|
|
Packit |
8681c6 |
4.1. [Slot Manager](#41-slot-manager)
|
|
Packit |
8681c6 |
4.2. [Main API](#42-main-api)
|
|
Packit |
8681c6 |
4.3. [Slot Token Dynamic Link
|
|
Packit |
8681c6 |
Libraries](#43-slot-token-dynamic-link-libraries)
|
|
Packit |
8681c6 |
4.4. [Shared Memory](#44-shared-memory)
|
|
Packit |
8681c6 |
5. [Getting Started with openCryptoki](#5-getting-started-with-opencryptoki)
|
|
Packit |
8681c6 |
5.1. [System Requirements](#51-system-requirements)
|
|
Packit |
8681c6 |
5.2. [Obtaining openCryptoki](#52-obtaining-opencryptoki)
|
|
Packit |
8681c6 |
5.3. [Compiling and Installing
|
|
Packit |
8681c6 |
openCryptoki](#53-compiling-and-installing-opencryptoki)
|
|
Packit |
8681c6 |
6. [Configuring openCryptoki](#6-configuring-opencryptoki)
|
|
Packit |
8681c6 |
7. [Components of openCryptoki](#7-components-of-opencryptoki)
|
|
Packit |
8681c6 |
7.1. [Slot Manager Daemon](#71-slot-manager-daemon)
|
|
Packit |
8681c6 |
7.2. [libopencryptoki.so](#72-libopencryptokiso)
|
|
Packit |
8681c6 |
7.3. [Slot Token DLLs](#73-slot-token-dlls)
|
|
Packit |
8681c6 |
7.3.1. [Trusted Module Platform](#731-trusted-module-platform-tpm)
|
|
Packit |
8681c6 |
7.3.2. [IBM Cryptographic Architecture (ICA)](#732-ibm-cryptographic-architecture-ica)
|
|
Packit |
8681c6 |
7.3.3. [IBM Common Cryptographic Architecture (CCA)](#733-ibm-common-cryptographic-architecture-cca)
|
|
Packit |
8681c6 |
7.3.4. [Software Token](#734-software-token)
|
|
Packit |
8681c6 |
7.3.5. [IBM Enterprise PKCS #11 (EP11)](#735-ibm-enterprise-pkcs-11-ep11)
|
|
Packit |
8681c6 |
7.3.6. [IBM Integrated Cryptographic Service Facility (ICSF)](#736-ibm-integrated-cryptographic-service-facility-icsf)
|
|
Packit |
8681c6 |
8. [Applications and openCryptoki](#8-application-and-opencryptoki)
|
|
Packit |
8681c6 |
8.1. [Making openCryptoki Available to
|
|
Packit |
8681c6 |
Applications](#81-making-opencryptoki-available-to-applications)
|
|
Packit |
8681c6 |
8.2. [Writing an Application](#82-writing-an-application)
|
|
Packit |
8681c6 |
9. [Resources](#9-resources)
|
|
Packit |
8681c6 |
10. [Appendix A: Sample Program](#10-appendix-a-sample-program)
|
|
Packit |
8681c6 |
10.1. [Sample Program](#101-sample-program)
|
|
Packit |
8681c6 |
10.2. [Makefile](#102-makefile)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 1. Copyright Notice and Disclaimer
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Copyright © 2001 - 2017 IBM Corporation. All rights reserved.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This document may be reproduced or distributed in any form without prior
|
|
Packit |
8681c6 |
permission provided the copyright notice is retained on all copies. Modified
|
|
Packit |
8681c6 |
versions of this document may be freely distributed, provided that they are
|
|
Packit |
8681c6 |
clearly identified as such, and this copyright is included intact.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This document is provided "AS IS," with no express or implied warranties. Use
|
|
Packit |
8681c6 |
the information in this document at your own risk.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
**Special Notices**
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This publication/presentation was produced in the United States. IBM may not
|
|
Packit |
8681c6 |
offer the products, programs, services or features discussed herein in other
|
|
Packit |
8681c6 |
countries, and the information may be subject to change without notice. Consult
|
|
Packit |
8681c6 |
your local IBM business contact for information on the products, programs,
|
|
Packit |
8681c6 |
services, and features available in your area. Any reference to an IBM product,
|
|
Packit |
8681c6 |
program, service, or feature is not intended to state or imply that only IBM’s
|
|
Packit |
8681c6 |
product, program, service, or feature may be used. Any functionally equivalent
|
|
Packit |
8681c6 |
product, program, service, or feature that does not infringe on IBM’s
|
|
Packit |
8681c6 |
intellectual property rights may be used instead.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Questions on the capabilities of non-IBM products should be addressed to
|
|
Packit |
8681c6 |
suppliers of those products. IBM may have patents or pending patent applications
|
|
Packit |
8681c6 |
covering subject matter in this presentation. Furnishing this presentation does
|
|
Packit |
8681c6 |
not give you any license to these patents. Send license inquiries, in writing,
|
|
Packit |
8681c6 |
to IBM Director of Licensing, IBM Corporation, New Castle Drive, Armonk, NY
|
|
Packit |
8681c6 |
10504-1785 USA. All statements regarding IBM’s future direction and intent are
|
|
Packit |
8681c6 |
subject to change or withdrawal without notice, and represent goals and
|
|
Packit |
8681c6 |
objectives only. Contact your local IBM office or IBM authorized reseller for
|
|
Packit |
8681c6 |
the full text of a specific Statement of General Direction.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The information contained in this presentation has not been submitted to any
|
|
Packit |
8681c6 |
formal IBM test and is distributed "AS IS." While each item may have have been
|
|
Packit |
8681c6 |
reviewed by IBM for accuracy in a specific situation, there is no guarantee that
|
|
Packit |
8681c6 |
the same or similar results will be obtained elsewhere. The use of this
|
|
Packit |
8681c6 |
information or the implementation of any techniques described herein is a
|
|
Packit |
8681c6 |
customer responsibility and depends on the customer’s ability to evaluate and
|
|
Packit |
8681c6 |
integrate them into the customer’s operational environment. Customers attempting
|
|
Packit |
8681c6 |
to adapt these techniques to their own environments do so at their own risk.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The information contained in this document represents the current views of IBM
|
|
Packit |
8681c6 |
on the issues discussed as of the date of publication. IBM cannot guarantee the
|
|
Packit |
8681c6 |
accuracy of any information presented after the date of publication.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Any performance data in this document was determined in a controlled
|
|
Packit |
8681c6 |
environment. Therefore, the results obtained in other operating environments may
|
|
Packit |
8681c6 |
vary significantly. Some measurements quoted in this book may have been made on
|
|
Packit |
8681c6 |
development-level systems. There is no guarantee these measurements will be the
|
|
Packit |
8681c6 |
same on generally-available systems. Some measurements quoted in this book may
|
|
Packit |
8681c6 |
have been estimated through extrapolation. Actual results may vary. Users of
|
|
Packit |
8681c6 |
this book should verify the applicable data for their specific environment.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
A full list of U.S. trademarks owned by IBM may be found at
|
|
Packit |
8681c6 |
http://www.ibm.com/legal/copytrade.shtml. Linux is a trademark of Linus
|
|
Packit |
8681c6 |
Torvalds. Other company, product, and service names may be trademarks or service
|
|
Packit |
8681c6 |
marks of others.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 2. Introduction
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Cryptography is rapidly becoming a critical part of our daily lives. However,
|
|
Packit |
8681c6 |
the application of cryptographic technology adds a heavy computational burden to
|
|
Packit |
8681c6 |
today's server platforms. More systems are beginning to use specialized hardware
|
|
Packit |
8681c6 |
to offload the computations, as well as to help ensure the security of secret
|
|
Packit |
8681c6 |
key material. In this HOWTO we will discuss openCryptoki, an API that is rapidly
|
|
Packit |
8681c6 |
becoming the defacto, non-Windows-platform industry standard for interfacing
|
|
Packit |
8681c6 |
between cryptographic hardware and user space applications. In particular we
|
|
Packit |
8681c6 |
will introduce the specifics of the PKCS #11 implementation to IBM cryptographic
|
|
Packit |
8681c6 |
hardware (openCryptoki).
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 3. What is openCryptoki?
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
openCryptoki is an implementation of the PKCS #11 API that allows interfacing to
|
|
Packit |
8681c6 |
devices (such as a smart card, smart disk, or PCMCIA card) that hold
|
|
Packit |
8681c6 |
cryptographic information and perform cryptographic functions. openCryptoki
|
|
Packit |
8681c6 |
provides application portability by isolating the application from the details
|
|
Packit |
8681c6 |
of the cryptographic device. Isolating the application also provides an added
|
|
Packit |
8681c6 |
level of security because all cryptographic information stays within the device.
|
|
Packit |
8681c6 |
The openCryptoki API provides a standard programming interface between
|
|
Packit |
8681c6 |
applications and all kinds of portable cryptographic devices.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 4. Architectural Overview
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
openCryptoki consists of a slot manager and an API for Slot Token Dynamic Link
|
|
Packit |
8681c6 |
Libraries (STDLLs). The slot manager runs as a daemon to control the number of
|
|
Packit |
8681c6 |
slots provided to applications, and it interacts with applications using a
|
|
Packit |
8681c6 |
shared memory region. Each device that has a token associated with it places
|
|
Packit |
8681c6 |
that token into a slot in the slot manager database. The shared memory region
|
|
Packit |
8681c6 |
allows for proper sharing of state information between applications to help
|
|
Packit |
8681c6 |
ensure conformance with the PKCS #11 specification.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 4.1. Slot Manager
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The Slot Manager Daemon (_pkcsslotd_) manages slots (and therefore tokens) in
|
|
Packit |
8681c6 |
the system. A fixed number of processes can be attached to _pkcsslotd_, so a
|
|
Packit |
8681c6 |
static table in shared memory is used. The current limit of the table is 1000
|
|
Packit |
8681c6 |
processes using the subsystem. The daemon sets up this shared memory upon
|
|
Packit |
8681c6 |
initialization and acts as a garbage collector thereafter, helping to ensure
|
|
Packit |
8681c6 |
that only active processes remain registered. When a process attaches to a slot
|
|
Packit |
8681c6 |
and opens a session, _pkcsslotd_ will make future processes aware that a process
|
|
Packit |
8681c6 |
has a session open and will lock out certain function calls, if the they need
|
|
Packit |
8681c6 |
exclusive access to the given token. The daemon will constantly search through
|
|
Packit |
8681c6 |
its region of shared memory and make sure that when a process is attached to a
|
|
Packit |
8681c6 |
token it is actually running. If an attached process terminates abnormally,
|
|
Packit |
8681c6 |
_pkcsslotd_ will "clean up" after the process and free the slot for use by other
|
|
Packit |
8681c6 |
processes.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 4.2. Main API
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The main API for the STDLLs lies in /usr/lib/opencryptoki/libopencryptoki.so.
|
|
Packit |
8681c6 |
This API includes all the functions as outlined in the PKCS #11 API
|
|
Packit |
8681c6 |
specification. The main API provides each application with the slot management
|
|
Packit |
8681c6 |
facility. The API also loads token specific modules (STDLLs) the provide the
|
|
Packit |
8681c6 |
token specific operations (cryptographic operations and session and object
|
|
Packit |
8681c6 |
management). STDLLs are customized for each token type and have specific
|
|
Packit |
8681c6 |
functions, such as an initialization routine, to allow the token to work with
|
|
Packit |
8681c6 |
the slot manager. When an application initializes the subsystem with the
|
|
Packit |
8681c6 |
__C_Initialize__ call, the API will load the STDLL shared objects for all the
|
|
Packit |
8681c6 |
tokens that exist in the configuration (residing in the shared memory) and
|
|
Packit |
8681c6 |
invoke the token specific initialization routines.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 4.3. Slot Token Dynamic Link Libraries
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
STDLLs are plug-in modules to the main API. They provide token-specific
|
|
Packit |
8681c6 |
functions beyond the main API functions. Specific devices can be supported by
|
|
Packit |
8681c6 |
building an STDLLs for the device. Each STDLLs must provide at least a token
|
|
Packit |
8681c6 |
specific initialization function. If the device is an intelligent device, such
|
|
Packit |
8681c6 |
as a hardware adapter that supports multiple mechanisms, the STDLL can be thin
|
|
Packit |
8681c6 |
because much of the session information can be stored on the device. If the
|
|
Packit |
8681c6 |
device only performs a simple cryptographic function, all of the objects must be
|
|
Packit |
8681c6 |
managed by the software. This flexibility allows the STDLLs to support any
|
|
Packit |
8681c6 |
cryptographic device.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 4.4. Shared Memory
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The slot manager sets up its database in a region of shared memory. Since the
|
|
Packit |
8681c6 |
maximum number of processes allowed to attach to _pkcsslotd_ is finite, a
|
|
Packit |
8681c6 |
fixed amount of memory can be set aside for token management. This fixed memory
|
|
Packit |
8681c6 |
allotment management allows applications easier access to token state
|
|
Packit |
8681c6 |
information and helps ensure conformance with the PKCS #11 specification.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 5. Getting Started with openCryptoki
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This section describes the system requirements for openCryptoki. It also
|
|
Packit |
8681c6 |
explains where you can get openCryptoki and how to compile and install it.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 5.1. System Requirements
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
openCryptoki installs by default a software token that relies on software to
|
|
Packit |
8681c6 |
deliver the crypto functions. So it is possible to install it even if you don't
|
|
Packit |
8681c6 |
have physical (hardware) token.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The following lists show the system requirements for running openCryptoki.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
**Hardware Requirements**
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
- openCryptoki is supported on ppc64, s390x and x86.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
**Software Requirements**
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
- Linux operating system running at least a 2.2.16 kernel
|
|
Packit |
8681c6 |
- Device drivers and associated support libraries for the installed tokens (some
|
|
Packit |
8681c6 |
of the header files from those distributions may also be required)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 5.2. Obtaining openCryptoki
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The openCryptoki project and source code is hosted on
|
|
Packit |
8681c6 |
[GitHub](https://github.com/opencryptoki/opencryptoki). You can find
|
|
Packit |
8681c6 |
openCryptoki releases (tarball) on GitHub and, as well, on
|
|
Packit |
8681c6 |
[SourceForge](https://sourceforge.net/projects/opencryptoki/).
|
|
Packit |
8681c6 |
For any issue, questions or development related subjects, please contact us on
|
|
Packit |
8681c6 |
the [mailing list](https://sourceforge.net/p/opencryptoki/mailman/).
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 5.3. Compiling and Installing openCryptoki
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Assuming that the device support (and header files) for the required devices are
|
|
Packit |
8681c6 |
on the system, then you can build openCryptoki by entering the source code main
|
|
Packit |
8681c6 |
directory and do the following:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
1. Run the bootstrap.sh script by typing:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ ./bootstrap.sh ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
2. Configure the source code by typing:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ ./configure ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
If you're planning to install the package into your home directory or to a
|
|
Packit |
8681c6 |
location other than `/usr/local` then add the flag `--prefix=PATH` to
|
|
Packit |
8681c6 |
`configure`. For example, if your home directory is `/home/luser` you can
|
|
Packit |
8681c6 |
configure the package to install itself there by invoking:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ ./configure --prefix=/home/luser ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
If your stdll headers and libraries are not under any standard path, you will
|
|
Packit |
8681c6 |
need to pass the paths to your files for the configure script. For instance:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ CPPFLAGS="-L/path/lib" LDFLAGS="-I/path/include" ./configure ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
See `./configure --help` for info on various options. The default behavior is
|
|
Packit |
8681c6 |
to build a default token implicitly. For the s390 platform, the default token
|
|
Packit |
8681c6 |
is ICA. For other platforms, the default token is the software token. Other
|
|
Packit |
8681c6 |
tokens may be enabled using the corresponding `--enable-<tok>` configuration
|
|
Packit |
8681c6 |
option provided the appropriate libraries are available.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
While running, `configure` prints some messages telling which features is it
|
|
Packit |
8681c6 |
checking for.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
3. Compile the package by typing:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ make ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
4. openCryptoki defaults to be usable by anyone who is in the group ``pkcs11``,
|
|
Packit |
8681c6 |
Add the pkcs11 group before installing it, by typing as root the command:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` # groupadd pkcs11 ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
In addition, add the necessary user to the pkcs11 group (root doesn't need to
|
|
Packit |
8681c6 |
be in the pkcs11 group):
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` # usermod -G pkcs11 <user> ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
5. Type `make install` (as root) to install the programs and any data files and
|
|
Packit |
8681c6 |
documentation. During installation, the following files go to the following
|
|
Packit |
8681c6 |
directories:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
/prefix/sbin/pkcsconf
|
|
Packit |
8681c6 |
/prefix/sbin/pkcsslotd
|
|
Packit |
8681c6 |
/prefix/sbin/pkcsicsf
|
|
Packit |
8681c6 |
/prefix/libdir/libopencryptoki.so
|
|
Packit |
8681c6 |
/prefix/libdir/libopencryptoki.so.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/libopencryptoki.so
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/libopencryptoki.so.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/libopencryptoki.so.0.0.0
|
|
Packit |
8681c6 |
/prefix/var/lib/opencryptoki
|
|
Packit |
8681c6 |
/prefix/etc/opencryptoki/opencryptoki.conf
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Token objects, which may be optionally built, go to the following locations:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_cca.so
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_cca.so.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_cca.so.0.0.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_ep11.so
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_ep11.so.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_ep11.so.0.0.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_ica.so
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_ica.so.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_ica.so.0.0.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_icsf.so
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_icsf.so.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_icsf.so.0.0.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_sw.so
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_sw.so.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_sw.so.0.0.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_tpm.so
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_tpm.so.0
|
|
Packit |
8681c6 |
/prefix/libdir/opencryptoki/stdll/libpkcs11_tpm.so.0.0.0
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
where `prefix` is either `/usr/local/` or the PATH that you specified in the
|
|
Packit |
8681c6 |
`--prefix` flag. `libdir` is the name of the library directory, for 32-bit
|
|
Packit |
8681c6 |
libraries it is usually `lib` and for 64-bit libraries it is usually `lib64`.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
To maintain backwards compatibility, some additional symlinks are generated
|
|
Packit |
8681c6 |
(note that these are deprecated and applications should migrate to use the
|
|
Packit |
8681c6 |
LSB-compliant name and locations for libraries and executable):
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
/prefix/lib/opencryptoki/PKCS11_API.so
|
|
Packit |
8681c6 |
- Symlink to /prefix/lib/opencryptoki/libopencryptoki.so
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/opencryptoki/stdll/PKCS11_CCA.so
|
|
Packit |
8681c6 |
- Symlink to /prefix/lib/opencryptoki/stdll/libpkcs11_cca.so
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/opencryptoki/stdll/PKCS11_EP11.so
|
|
Packit |
8681c6 |
- Symlink to /prefix/lib/opencryptoki/stdll/libpkcs11_ep11.so
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/opencryptoki/stdll/PKCS11_ICA.so
|
|
Packit |
8681c6 |
- Symlink to /prefix/lib/opencryptoki/stdll/libpkcs11_ica.so
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/opencryptoki/stdll/PKCS11_ICSF.so
|
|
Packit |
8681c6 |
- Symlink to /prefix/lib/opencryptoki/stdll/libpkcs11_icsf.so
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/opencryptoki/stdll/PKCS11_SW.so
|
|
Packit |
8681c6 |
- Symlink to /prefix/lib/opencryptoki/stdll/libpkcs11_sw.so
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/pkcs11/PKCS11_API.so
|
|
Packit |
8681c6 |
- Symlink to /prefix/lib/opencryptoki/libopencryptoki.so
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/pkcs11
|
|
Packit |
8681c6 |
- Directory created if non-existent
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/pkcs11/methods
|
|
Packit |
8681c6 |
- Symlink to /prefix/sbin
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/lib/pkcs11/stdll
|
|
Packit |
8681c6 |
- Symlink to /prefix/lib/opencryptoki/stdll
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/prefix/etc/pkcs11
|
|
Packit |
8681c6 |
- Symlink to /prefix/var/lib/opencryptoki
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
If any of these directories do not presently exist, they will be created on
|
|
Packit |
8681c6 |
demand. Note that if `prefix` is `/usr`, then `/prefix/var` and `/prefix/etc`
|
|
Packit |
8681c6 |
resolve to `/var` and `/etc`. On the `make install` stage, if content exists
|
|
Packit |
8681c6 |
in the old `/prefix/etc/pkcs11` directory, it will be migrated to the new
|
|
Packit |
8681c6 |
`/prefix/var/lib/opencryptoki` location.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
If you are installing in your home directory make sure that `/home/luser/bin`
|
|
Packit |
8681c6 |
is in your path. If you're using the bash shell add this line at the end of
|
|
Packit |
8681c6 |
your `.bashrc` file:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
PATH="/home/luser/bin:${PATH}"
|
|
Packit |
8681c6 |
export PATH
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
If you are using csh or tcsh, then use this line instead:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` setenv PATH /home/luser/bin:${PATH} ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
By prepending your home directory to the rest of the PATH you can override
|
|
Packit |
8681c6 |
systemwide installed software with your own custom installation.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 6. Configuring openCryptoki
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
See:
|
|
Packit |
8681c6 |
https://www.ibm.com/support/knowledgecenter/linuxonibm/com.ibm.linux.z.lxce/lxce_stackoverview.html
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Prior to version 3, openCryptoki used `pk_config_data` as its configuration
|
|
Packit |
8681c6 |
file. This file was created upon running `pkcs11_startup`. In version 3,
|
|
Packit |
8681c6 |
`pkcs11_startup` and `pk_config_data` have been removed and replaced with a
|
|
Packit |
8681c6 |
customizable config file named, `opencryptoki.conf`. It contains an entry for
|
|
Packit |
8681c6 |
each token currently supported by openCryptoki. However, only those token, whose
|
|
Packit |
8681c6 |
hardware and software requirements are available on the local system, will show
|
|
Packit |
8681c6 |
up as present and available upon running the `pkcsconf -t` command.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Before using, each token must be first initialized. You can select the token
|
|
Packit |
8681c6 |
with the `-c` command line option; refer to the documentation linked to above
|
|
Packit |
8681c6 |
for further instructions.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Initialize a particular token by running `pkcsconf`:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ pkcsconf -I -c ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
In this version of openCryptoki, the default SO PIN is `87654321`. This should
|
|
Packit |
8681c6 |
be changed to a different PIN value before use.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
You can change the SO PIN by running pkcsconf :
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ pkcsconf -P -c ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
You can initialize and change the user PIN by typing:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ pkcsconf -u -c ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
You can later change the user PIN again by typing:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` $ pkcsconf -p -c ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 7. Components of openCryptoki
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This section describes the different components of the openCryptoki subsystem.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 7.1. Slot Manager Daemon
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The slot manager daemon is an executable (`/usr/sbin/pkcsslotd`) that reads in
|
|
Packit |
8681c6 |
`/etc/opencryptoki/opencryptoki.conf`, populating shared memory according to
|
|
Packit |
8681c6 |
what devices have been found within the system. `pkcsslotd` then continues
|
|
Packit |
8681c6 |
running as a daemon. Any other applications attempting to use the subsystem must
|
|
Packit |
8681c6 |
first attach to the shared memory region and register as part of the API
|
|
Packit |
8681c6 |
initialization process, so `pkcsslotd` is aware of the application. If
|
|
Packit |
8681c6 |
`/etc/opencryptoki/opencryptoki.conf/` is changed, `pkcsslotd` must be stopped
|
|
Packit |
8681c6 |
and restarted to read in the new configuration file. The daemon can be stopped
|
|
Packit |
8681c6 |
by issuing the `pkill pkcsslotd` command or through systemd `systemctl stop
|
|
Packit |
8681c6 |
pkcsslotd`. The daemon will not terminate if there are any applications using
|
|
Packit |
8681c6 |
the subsystem.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 7.2. libopencryptoki.so
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This library contains the main API (`/usr/lib/opencryptoki/libopencryptoki.so`)
|
|
Packit |
8681c6 |
and is loaded by any application that uses any PKCS #11 token managed by the
|
|
Packit |
8681c6 |
subsystem. Before an application uses a token, it must load the API and call
|
|
Packit |
8681c6 |
`C_Initialize`, as per the PKCS #11 specification. The loading operation is
|
|
Packit |
8681c6 |
performed by the application using the dlopen facilities.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 7.3. Slot Token DLLs
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Six STDLLs ship in the initial offering. These support Trusted Platfrom Module
|
|
Packit |
8681c6 |
(TPM, <2.0), IBM Cryptographic Architecture (ICA), IBM Common Cryptographic
|
|
Packit |
8681c6 |
Architecture (CCA), Soft Token, IBM Enterprise PKCS #11 (EP11) and IBM
|
|
Packit |
8681c6 |
Integrated Cryptographic Service Facility (ICSF).
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
**Note**: The compilation process attempts to build all of the tokens that
|
|
Packit |
8681c6 |
are supported on the target platform, as well as all of the required support
|
|
Packit |
8681c6 |
programs. If some of the headers and libraries are not present, those
|
|
Packit |
8681c6 |
components will not be built.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
##### 7.3.1. Trusted Module Platform (TPM)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
In order to be able to build the TPM stdll you first need:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
1. Enable tpm in BIOS settings.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
2. Install trousers, trousers-devel, tpm-tools and tpm-tools-pkcs11 as root.
|
|
Packit |
8681c6 |
Package names can differ depending on the Linux distribution.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
3. As root run the following commands:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
Start the tcsd daemon
|
|
Packit |
8681c6 |
# /etc/init.d/tcsd start or # systemctl start tcsd
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Enter tpm passwords
|
|
Packit |
8681c6 |
# tpm_takeownership
|
|
Packit |
8681c6 |
Enter owner password:
|
|
Packit |
8681c6 |
Confirm password:
|
|
Packit |
8681c6 |
Enter SRK password:
|
|
Packit |
8681c6 |
Confirm password:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
# tpm_setpresence
|
|
Packit |
8681c6 |
Enter owner password:
|
|
Packit |
8681c6 |
Physical Presence Status:
|
|
Packit |
8681c6 |
Command Enable: true
|
|
Packit |
8681c6 |
Hardware Enable: false
|
|
Packit |
8681c6 |
Lifetime Lock: true
|
|
Packit |
8681c6 |
Physical presence: false
|
|
Packit |
8681c6 |
Lock: true
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
After setting up the TPM the openCryptoki compilation should automatically
|
|
Packit |
8681c6 |
build the tpm stdll. If it doesn't, then please run:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
``` ./configure --enable-tpmtok ```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
For more information check [README.tpm_stdll](README.tpm_stdll)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
##### 7.3.2. IBM Cryptographic Architecture (ICA)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The IBM Cryptographic Architecture (ICA) is a hardware token that is available
|
|
Packit |
8681c6 |
only for s390 systems. If you are in this platform and have the necessary
|
|
Packit |
8681c6 |
hardware, you can build openCryptoki with the ICA stdll. To achieve it you need
|
|
Packit |
8681c6 |
first install the `libica` package. This package is available in the Linux
|
|
Packit |
8681c6 |
distributions repositories.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
##### 7.3.3. IBM Common Cryptographic Architecture (CCA)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The IBM Common Cryptographic Architecture (CCA) is also a hardware token that is
|
|
Packit |
8681c6 |
only available for the s390 architecture. If you are in this platform and have
|
|
Packit |
8681c6 |
the necessary hardware then you can build openCryptoki with the CCA stdll.
|
|
Packit |
8681c6 |
First, you need to install the csulcca library on your system. To get this
|
|
Packit |
8681c6 |
package click
|
|
Packit |
8681c6 |
[here](https://www-03.ibm.com/security/cryptocards/pciecc2/lonzsoftware.shtml)
|
|
Packit |
8681c6 |
and be sure to choose the package corresponding to your crypto card version.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
For more information about CCA, read [README.cca_stdll](README.cca_stdll)
|
|
Packit |
8681c6 |
and [README.pkcscca_migrate](README.pkcscca_migrate).
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
##### 7.3.4. Software Token
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This token is a software emulation of a token. All the cryptographic operations
|
|
Packit |
8681c6 |
needed will be run in a software implementation of such cryptographic
|
|
Packit |
8681c6 |
algorithms. This implementation is given by OpenSSL and the Soft token is built
|
|
Packit |
8681c6 |
by default with openCryptoki.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
##### 7.3.5. IBM Enterprise PKCS #11 (EP11)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This is another hardware token for the s390 architecture. In order to be able to
|
|
Packit |
8681c6 |
build openCryptoki with EP11 stdll download the necessary library from
|
|
Packit |
8681c6 |
[here](https://www-03.ibm.com/security/cryptocards/pciecc2/lonzsoftware.shtml).
|
|
Packit |
8681c6 |
Be sure to choose the driver corresponding to your crypto card version.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
For more information about EP11, please refer to
|
|
Packit |
8681c6 |
[README.ep11_stdll](README.ep11_stdll).
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
##### 7.3.6. IBM Integrated Cryptographic Service Facility (ICSF)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The ICSF token is a remote crypto token. The actual crypto operations are
|
|
Packit |
8681c6 |
performed remotely on a s390 server and all the PKCS #11 key objects are stored
|
|
Packit |
8681c6 |
remotely on the server. This calls to the remote server are done via LDAP.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
So, to build openCryptoki with LDAP, you need to install on the client side:
|
|
Packit |
8681c6 |
`openldap, openldap-clients and openldap-devel`.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
For more information about ICSF, head over to
|
|
Packit |
8681c6 |
[README.icsf_stdll](README.icsf_stdll).
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 8. Application and openCryptoki
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
This section describes how to make openCryptoki available to applications and
|
|
Packit |
8681c6 |
provides an example of how to write such an application.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 8.1. Making openCryptoki Available to Applications
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Many applications use PKCS #11 tokens. Most of these applications must be
|
|
Packit |
8681c6 |
configured to load specific shared object (DLL) for the token. In the case of
|
|
Packit |
8681c6 |
openCryptoki, only one module (`/usr/lib/opencryptoki/libopencryptoki.so`) must
|
|
Packit |
8681c6 |
be loaded for access to all the tokens currently running in the subsystem.
|
|
Packit |
8681c6 |
Multiple token types are supported, with each type taking up a slot in the
|
|
Packit |
8681c6 |
subsystem according to the implementation specifics of the plug-in module.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
If devices are added or removed, the PKCS #11 slot where the token resides may
|
|
Packit |
8681c6 |
change. For this reason, applications should locate the specific token by the
|
|
Packit |
8681c6 |
token label provided when the token is initialized and not assume that a
|
|
Packit |
8681c6 |
specific slot always contains the desired token.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
For application-specific configuration information relating to the exploitations
|
|
Packit |
8681c6 |
of PKCS #11, refer to the application's documentation.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 8.2. Writing an Application
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
To develop an application that uses openCryptoki, you must first load the shared
|
|
Packit |
8681c6 |
object using the dynamic library calls. Then call C_GetFunctionList. For
|
|
Packit |
8681c6 |
example, the following routines loads the shared library and gets the function
|
|
Packit |
8681c6 |
list for subsequent calls.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
CK_FUNCTION_LIST *funcs;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
int do_GetFunctionList(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_RV (*pfoo)();
|
|
Packit |
8681c6 |
void *d;
|
|
Packit |
8681c6 |
char *e;
|
|
Packit |
8681c6 |
char f[]="/usr/lib/pkcs11/PKCS11_API.so"
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
printf("do_GetFunctionList...\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
d = dlopen(f, RTLD_NOW);
|
|
Packit |
8681c6 |
if (d == NULL)
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pfoo = (CK_RV (*)())dlsym(d, "C_GetFunctionList");
|
|
Packit |
8681c6 |
if (pfoo == NULL)
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = pfoo(&funcs);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
show_error("C_GetFunctionList rc=%d\n", rc);
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
printf("Looks okay...\n");
|
|
Packit |
8681c6 |
return TRUE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Once loaded, the application must call the `C_Initialize` function. In the
|
|
Packit |
8681c6 |
previous example, the function would be invoked with the following lines:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
CK_C_INITIALIZE_ARGS cinit_args;
|
|
Packit |
8681c6 |
memset(&cinit_args, 0x0, sizeof(cinit_args));
|
|
Packit |
8681c6 |
funcs->C_Initialize(&cinit_args);
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Refer to the PKCS #11 specification available from the OASIS web site
|
|
Packit |
8681c6 |
(https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=pkcs11) for more
|
|
Packit |
8681c6 |
options.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
**Note**: openCryptoki requires that operating systems threads be allowed. If
|
|
Packit |
8681c6 |
other thread routines are passed in, they are ignored. If the `no-os` threads
|
|
Packit |
8681c6 |
argument is set in the initialize arguments structure, the call to
|
|
Packit |
8681c6 |
C_Initialize will fail.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 9. Resources
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
For additional information about PKCS #11 and openCryptoki, see the following
|
|
Packit |
8681c6 |
resources:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
* openCryptoki on [GitHub](https://github.com/opencryptoki/opencryptoki)
|
|
Packit |
8681c6 |
* OASIS [PKCS #11 Specification](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=pkcs11)
|
|
Packit |
8681c6 |
* [IBM Cryptocards](https://www-03.ibm.com/security/cryptocards/)
|
|
Packit |
8681c6 |
* openCryptoki
|
|
Packit |
8681c6 |
[mailing-list](https://sourceforge.net/projects/opencryptoki/lists/opencryptoki-tech)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
### 10. Appendix A: Sample Program
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
The following sample program prints out all of the current tokens and slots in
|
|
Packit |
8681c6 |
use in the system. If you want to build the sample program, you will also need
|
|
Packit |
8681c6 |
the `Makefile` after the sample.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 10.1. Sample Program
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
#include <sys/stat.h>
|
|
Packit |
8681c6 |
#include <stdlib.h>
|
|
Packit |
8681c6 |
#include <errno.h>
|
|
Packit |
8681c6 |
#include <stdio.h>
|
|
Packit |
8681c6 |
#include <dlfcn.h>
|
|
Packit |
8681c6 |
#include <pkcs11types.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#define CFG_SLOT 0x0004
|
|
Packit |
8681c6 |
#define CFG_PKCS_INFO 0X0008
|
|
Packit |
8681c6 |
#define CFG_TOKEN_INFO 0x0010
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV init(void);
|
|
Packit |
8681c6 |
CK_RV cleanup(void);
|
|
Packit |
8681c6 |
CK_RV get_slot_list(int, CK_CHAR_PTR);
|
|
Packit |
8681c6 |
CK_RV display_slot_info(void);
|
|
Packit |
8681c6 |
CK_RV display_token_info(void);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
void *dll_ptr;
|
|
Packit |
8681c6 |
CK_FUNCTION_LIST_PTR function_ptr = NULL;
|
|
Packit |
8681c6 |
CK_SLOT_ID_PTR slot_list = NULL;
|
|
Packit |
8681c6 |
CK_ULONG slot_count = 0;
|
|
Packit |
8681c6 |
int in_slot;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
int main(int argc, char *argv[])
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc; /* Return Code */
|
|
Packit |
8681c6 |
CK_FLAGS flags = 0; /* Bit Mask for what options were passed in */
|
|
Packit |
8681c6 |
CK_CHAR_PTR slot = NULL; /* The PKCS slot number */
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Load the PKCS11 library */
|
|
Packit |
8681c6 |
init();
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Get the slot list and indicate if a slot number was passed in or not */
|
|
Packit |
8681c6 |
get_slot_list(flags, slot);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Display the current token and slot info */
|
|
Packit |
8681c6 |
display_token_info();
|
|
Packit |
8681c6 |
display_slot_info();
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* We are done, free the memory we may have allocated */
|
|
Packit |
8681c6 |
free(slot);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV get_slot_list(int cond, CK_CHAR_PTR slot)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc; /* Return code */
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Find out how many tokens are present in the slots */
|
|
Packit |
8681c6 |
rc = function_ptr->C_GetSlotList(TRUE, NULL_PTR, &slot_count);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
printf("Error getting number of slots: 0x%X\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Allocate enough space for the slots information */
|
|
Packit |
8681c6 |
slot_list = (CK_SLOT_ID_PTR) malloc(slot_count*sizeof(CK_SLOT_ID));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = function_ptr->C_GetSlotList(TRUE, slot_list, &slot_count);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
printf("Error getting slot list: 0x%X\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV display_slot_info(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc; /* Return Code */
|
|
Packit |
8681c6 |
CK_SLOT_INFO slot_info; /* Structure to hold slot information */
|
|
Packit |
8681c6 |
int lcv; /* Loop Control Variable */
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
for (lcv = 0; lcv < slot_count; lcv++) {
|
|
Packit |
8681c6 |
/* Get the info for the slot we are examining and store in slot_info */
|
|
Packit |
8681c6 |
rc = function_ptr->C_GetSlotInfo(slot_list[lcv], &slot_info);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
printf("Error getting the slot info: 0x%X\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Display the slot information */
|
|
Packit |
8681c6 |
printf("Slot #%d Info\n", slot_list[lcv]);
|
|
Packit |
8681c6 |
printf("\tDescription: %.64s\n", slot_info.slotDescription);
|
|
Packit |
8681c6 |
printf("\tManufacturer: %.32s\n", slot_info.manufacturerID);
|
|
Packit |
8681c6 |
printf("\tFlags: 0x%X\n", slot_info.flags);
|
|
Packit |
8681c6 |
printf("\tHardware Version: %d.%d\n", slot_info.hardwareVersion.major,
|
|
Packit |
8681c6 |
slot_info.hardwareVersion.minor);
|
|
Packit |
8681c6 |
printf("\tFirmware Version: %d.%d\n", slot_info.firmwareVersion.major,
|
|
Packit |
8681c6 |
slot_info.firmwareVersion.minor);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV display_token_info(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc; /* Return Code */
|
|
Packit |
8681c6 |
CK_TOKEN_INFO token_info; /* Structure to hold token information */
|
|
Packit |
8681c6 |
int lcv; /* Loop Control Variable */
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
for (lcv = 0; lcv < slot_count; lcv++) {
|
|
Packit |
8681c6 |
/* Get the Token info for each slot in the system */
|
|
Packit |
8681c6 |
rc = function_ptr->C_GetTokenInfo(slot_list[lcv], &token_info);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
printf("Error getting token info: 0x%X\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Display the token information */
|
|
Packit |
8681c6 |
printf("Token #%d Info:\n", slot_list[lcv]);
|
|
Packit |
8681c6 |
printf("\tLabel: %.32s\n", token_info.label);
|
|
Packit |
8681c6 |
printf("\tManufacturer: %.32s\n", token_info.manufacturerID);
|
|
Packit |
8681c6 |
printf("\tModel: %.16s\n", token_info.model);
|
|
Packit |
8681c6 |
printf("\tSerial Number: %.16s\n", token_info.serialNumber);
|
|
Packit |
8681c6 |
printf("\tFlags: 0x%X\n", token_info.flags);
|
|
Packit |
8681c6 |
printf("\tSessions: %d/%d\n", token_info.ulSessionCount,
|
|
Packit |
8681c6 |
token_info.ulMaxSessionCount);
|
|
Packit |
8681c6 |
printf("\tR/W Sessions: %d/%d\n", token_info.ulRwSessionCount,
|
|
Packit |
8681c6 |
token_info.ulMaxRwSessionCount);
|
|
Packit |
8681c6 |
printf("\tPIN Length: %d-%d\n", token_info.ulMinPinLen,
|
|
Packit |
8681c6 |
token_info.ulMaxPinLen);
|
|
Packit |
8681c6 |
printf("\tPublic Memory: 0x%X/0x%X\n", token_info.ulFreePublicMemory,
|
|
Packit |
8681c6 |
token_info.ulTotalPublicMemory);
|
|
Packit |
8681c6 |
printf("\tPrivate Memory: 0x%X/0x%X\n", token_info.ulFreePrivateMemory,
|
|
Packit |
8681c6 |
token_info.ulTotalPrivateMemory);
|
|
Packit |
8681c6 |
printf("\tHardware Version: %d.%d\n", token_info.hardwareVersion.major,
|
|
Packit |
8681c6 |
token_info.hardwareVersion.minor);
|
|
Packit |
8681c6 |
printf("\tFirmware Version: %d.%d\n", token_info.firmwareVersion.major,
|
|
Packit |
8681c6 |
token_info.firmwareVersion.minor);
|
|
Packit |
8681c6 |
printf("\tTime: %.16s\n", token_info.utcTime);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV init(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc; /* Return Code */
|
|
Packit |
8681c6 |
void (*sym_ptr)(); /* Pointer for the DLL */
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Open the PKCS11 API Shared Library, and inform the user if there is an
|
|
Packit |
8681c6 |
* error
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
dll_ptr = dlopen("/usr/lib/opencryptoki/libopencryptoki.so", RTLD_NOW);
|
|
Packit |
8681c6 |
if (!dll_ptr) {
|
|
Packit |
8681c6 |
rc = errno;
|
|
Packit |
8681c6 |
printf("Error loading PKCS#11 library: 0x%X\n", rc);
|
|
Packit |
8681c6 |
fflush(stdout);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Get the list of the PKCS11 functions this token supports */
|
|
Packit |
8681c6 |
sym_ptr = (void (*) ())dlsym(dll_ptr, "C_GetFunctionList");
|
|
Packit |
8681c6 |
if (!sym_ptr) {
|
|
Packit |
8681c6 |
rc = errno;
|
|
Packit |
8681c6 |
printf("Error getting function list: 0x%X\n", rc);
|
|
Packit |
8681c6 |
fflush(stdout);
|
|
Packit |
8681c6 |
cleanup();
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
sym_ptr(&function_ptr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* If we get here, we know the slot manager is running and we can use PKCS11
|
|
Packit |
8681c6 |
* calls, so we will execute the PKCS11 Initialize command.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
rc = function_ptr->C_Initialize(NULL);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
printf("Error initializing the PKCS11 library: 0x%X\n", rc);
|
|
Packit |
8681c6 |
fflush(stdout);
|
|
Packit |
8681c6 |
cleanup();
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV cleanup(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc; /* Return Code */
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* To clean up we will free the slot list we create, call the Finalize
|
|
Packit |
8681c6 |
* routine for PKCS11 and close the dynamically linked library
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
free(slot_list);
|
|
Packit |
8681c6 |
rc = function_ptr->C_Finalize(NULL);
|
|
Packit |
8681c6 |
if (dll_ptr)
|
|
Packit |
8681c6 |
dlclose(dll_ptr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
exit(rc);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#### 10.2. Makefile
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
```
|
|
Packit |
8681c6 |
VPATH = ...
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
INCS = -I../. -I../../../../../include/pkcs11
|
|
Packit |
8681c6 |
CFLAGS = $(OPTLVL) $(INCS) -DAPI -DDEV -D_THREAD_SAFE -DLINUX -DDEBUG -DSPINXL
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CC = gcc
|
|
Packit |
8681c6 |
LD = gcc
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
LIBS = -ldl -lpthread
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
OBJS = sample.o
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
.c.o: ; $(CC) -c $(CFLAGS) -o $@ $<
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
all: sample
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
sample: $(OBJS)
|
|
Packit |
8681c6 |
${CC} ${OBJS} $(LIBS) -o $@
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TARGET = sample
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
build: $(TARGET)
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
clean:
|
|
Packit |
8681c6 |
rm -f *.so *.o $(TARGET)
|
|
Packit |
8681c6 |
```
|