Personal Desktop PKCS#11
Personal Desktop includes a PKCS#11 compliant library. By using this library, third party applications can interact with the cryptographic functions and tokens in the underlying Personal Desktop Token-API. Personal Desktop PKCS#11 is optimized for use with SSL in Mozilla-based browsers to access secure web sites.
Implemented API functions
Function | Description |
---|---|
General purpose | |
| Initializes Cryptoki. |
| Cleans up miscellaneous Cryptoki functions. |
| Obtains general information about Cryptoki. |
| Obtains entry points of Cryptoki library functions. |
Slot and Token Management | |
| Obtains a list of slots in the system. |
| Obtains information about a particular slot. |
| Obtains information about a particular token. |
| Obtains a list of mechanisms supported by a token. |
| Obtains information about a particular mechanism. |
| Modifies the PIN of the user that is currently logged in. |
| Waits for slot event (token insertion, removal etc.) to occur. |
| Can be used to unblock a PIN. |
| |
| |
| |
Session Management | |
| Opens a connection or “session” between an application and a particular token. |
| Closes a session. |
| Closes all sessions with a token. |
| Obtains information about the session. |
| Logs into a token. Only CKU_USER is supported for soft tokens. |
| Logs out from a token. |
Object Management | |
| Creates a new object. |
| Copies an object, creating a new object for the copy. |
| Destroys an object. |
| Obtains an attribute value of an object. |
| Modifies the value of one or more attributes of an object. |
| Initializes an object search operation. |
| Continues an object search operation. |
| Finishes an object search operation. |
Encryption and Decryption | |
| Initializes an encryption operation. |
| Encrypts single-part data. |
| Continues a multiple-part encryption operation. |
| Finishes a multiple-part encryption operation. |
| Initializes a decryption operation. |
| Decrypts single-part encrypted data. |
| Continues a multiple-part decryption operation. |
| Finishes a multiple-part decryption operation. |
Message Digesting | |
| Initializes a message-digesting operation. |
| Digests data in a single part. |
| Continues a multiple-part digesting operation. |
| Finishes a multiple-part digesting operation. |
Signing and Verifying | |
| Initializes a signature operation. |
| Signs single part data. |
| Continues a multiple-part signing operation. |
| Finishes a multiple-part signing operation. |
| Initializes a signature operation, where the data can be recovered from the signature. |
| Signs single-part data, where the data can be recovered from the signature. |
| Initializes a verification operation. |
| Verifies a signature on single-part data. |
| Initializes a verification operation where the data is recovered from the signature. |
| Verifies single-part data, where the data can be recovered from the signature. |
Key Management | |
| Generates a public/private key pair, creating new key objects. |
| Wraps (that is, encrypts) a key. |
| Unwraps (that is, decrypts) a wrapped key, creating a new private key or secret key object. |
Random Number Generation | |
| Mixes additional seed material into the token’s random number generator. |
| Generates random or pseudo-random data. |
*This function is not a member of the PKCS#11 v2.20 specification.
Exceptions from the PKCS#11 specification
The PKCS#11 v2.20 specification is the complete documentation of the API implemented by Personal Desktop PKCS#11. This section describes exceptions from the PKCS#11 specification.
Function | Exception |
---|---|
| Each physical smart card token will, by default, be shown as two virtual tokens to allow multiple PIN codes on a smart card. If only one PIN is available, then the second slot will be empty. |
| Only CKU_USER is supported for software tokens. |
| A return value is added: CKR_TEMPLATE_INCONSISTENT |
| A return value is added: CKR_FUNCTION_NOT_PERMITTED |
| A return value is added: CKR_FUNCTION_NOT_PERMITTED |
| CK_RV C_UnblockPIN (CK_SESSION_HANDLE
|
| CK_RV C_InitTokenPPA (CK_SLOT_ID
|
| CK_RV C_GetProperty (CK_SESSION_HANDLE
|
| CK_RV C_SetSlotProperty (CK_SLOT_ID
|
Serialization of Java map
The C_InitTokenPPA
function takes an optional map of variables, as a map serialized to a byte array. The format of the serialization is:
For each key-value pair in the map a 0x01 byte precedes the key.
After a key, a 0x02 byte precedes the corresponding value.
If the value is empty (that is, consists of no data at all), the 0x02 byte is optional.
At the very end of the map a 0x03 byte marks the end.
If a key or value contains one or more 0x01, 0x02, 0x03 or 0xB1 bytes, each one must be “escaped” by prefixing it with a 0xB1 byte.
Keys must be unique, that is, no key value may appear more than once.
Neither keys nor values are null-terminated; their lengths are specified by the appearances of the “special” bytes.
The syntax for a map containing n key-value pairs may be described as:
0x01 <key 1> [ 0x02 <value 1> ]
0x01 <key 2> [ 0x02 <value 2> ]
.
.
.
0x01 <key n> [ 0x02 <value n> ]
0x03
PIN data URI
According to the PKCS#11 specification, PINs should contain only UTF-8 characters. However, under certain circumstances it is required to use PINs that are not valid UTF-8 strings. For example factory Management Key on the PIV card is derived from the PIV Context Value using symmetric encryption algorithm and is not a valid UTF-8 string. Personal Desktop PKCS#11 module uses PIV Management Key as PIN for CKU_SO user and needs to bypass this limitation. For this purpose PIN can be encoded using data URI scheme.
The syntax of data URIs was defined in RFC 2397, and follows the URI scheme syntax. A data URI consists of:
data:[<media type>][;charset=<character set>][;base64],<data>
Explanation:
The scheme,
data
, is followed by a colon (:)<
media type
> optional, at the moment this parameter is ignored.<
character set
> optional, at the moment this parameter is ignored.base64
optional. separated from the preceding part by a semicolon (;). When present, this indicates that the <data> of the URI is encoded using Base64 scheme.<
data>
the actual data, separated from the preceding part by a comma (,).
Below are some valid examples of PIN encoded with data URI scheme:
"data:,12345" // PIN is "12345"
"data:text/plain;base64,MTIzNDU=" // PIN is "12345"
"data:text/plain;charset=US-ASCII;base64,MTIzNDU=" // PIN is "12345"
"data:text/plain;base64,ABEiM0RV" // PIN is 0x001122334455 (binary)
"data:;base64,MTIzNDU2" // PIN is "123456"
These API functions support PIN data URI:
C_Login
C_SetPIN
C_UnblockPIN
If a UTF-8 string passed as a parameter for one of the above API functions does not match the data URI scheme, it will be handled as an usual PIN according to PKCS#11 specification.
Properties
This table describes the properties that can be used with Personal Desktop's PKCS#11 module, and whether they can be gotten (using C_GetProperty
) and/or set (using C_SetSlotProperty
).
Key | Get | Set (Slot) | Description |
---|---|---|---|
| ✓ | Gets a card's chip serial number. Only works for sessions whose slots contain a smart card type token. | |
| ✓ | Sets an SM (Secure Messaging) key. After such a key has been set, communication with a card will use Secure Messaging. Should only be set on slots that contain a smart card token. Should be set before |
Header file
The following header file can be used for programming against Personal Desktop's PKCS#11 module:
/*
* Copyright (c) 2013 Technology Nexus AB
*
* This is proprietary software and is the property of Technology Nexus AB. No
* sale, reproduction or other use of this program is authorized except as
* granted by the fully executed Technology Nexus AB product license.
*
*/
/*
* This file contains neXus extensions to PKCS#11. To work properly, it should
* be included from `pkcs11f.h`.
*/
CK_PKCS11_FUNCTION_INFO(C_UnblockPIN)
# ifdef CK_NEED_ARG_LIST
(
/* *INDENT-OFF* */
CK_SESSION_HANDLE hSession,
CK_CHAR* pPin,
CK_ULONG ulPinLen,
CK_CHAR* pPuk,
CK_ULONG ulPukLen
/* *INDENT-ON* */
);
# endif
CK_PKCS11_FUNCTION_INFO(C_InitTokenPPA)
# ifdef CK_NEED_ARG_LIST
(
/* *INDENT-OFF* */
CK_SLOT_ID slotID,
CK_UTF8CHAR_PTR pScript,
CK_ULONG ulScriptLen,
CK_UTF8CHAR_PTR pVariables,
CK_ULONG ulVariables
/* *INDENT-ON* */
);
# endif
CK_PKCS11_FUNCTION_INFO(C_GetProperty)
# ifdef CK_NEED_ARG_LIST
(
/* *INDENT-OFF* */
CK_SESSION_HANDLE hSession,
CK_CHAR_PTR pProperty,
CK_CHAR_PTR pResult,
CK_ULONG_PTR pulCount
/* *INDENT-ON* */
);
# endif
CK_PKCS11_FUNCTION_INFO(C_SetSlotProperty)
# ifdef CK_NEED_ARG_LIST
(
/* *INDENT-OFF* */
CK_SLOT_ID slotID,
CK_CHAR_PTR pProperty,
CK_CHAR_PTR pValue,
CK_ULONG pulValue
/* *INDENT-ON* */
);
# endif
#if !defined(CKM_ID2_MECHANISM_BASE)
# define CKM_ID2_MECHANISM_BASE 0x00694432
# define CKM_RSA_CSSD \
(CKM_VENDOR_DEFINED + CKM_ID2_MECHANISM_BASE + 1)
/*
* NIST 800-38A AES CBC mechanisms for Siemens Card OS 5.0 cards.
*/
# define CKM_AES_CBC_NIST_ISOPAD \
(CKM_VENDOR_DEFINED + CKM_ID2_MECHANISM_BASE + 2)
# define CKM_AES_CBC_NIST_ANSIPAD \
(CKM_VENDOR_DEFINED + CKM_ID2_MECHANISM_BASE + 3)
# define CKR_HW_RNG_NO_READER (CKR_VENDOR_DEFINED + 0x1001)
# define CKR_HW_RNG_NO_CARD (CKR_VENDOR_DEFINED + 0x1002)
# define CKR_HW_RNG_NO_CARD_RNG (CKR_VENDOR_DEFINED + 0x1003)
/*
* Nexus-Defined Mechanisms
*/
#define NGM_AES_CBC_NIST_ISOPAD (CKR_VENDOR_DEFINED | 0x694434)
#define NGM_AES_CBC_NIST_ANSIPAD (CKR_VENDOR_DEFINED | 0x694435)
/*
* Keys for properties used by C_GetProperty and C_SetSlotProperty.
*/
/** SM (Secure Messaging) key */
# define PROPERTY_KEY_SMKEY "smkey"
# define PROPERTY_KEY_CHIPSERIAL "ChipSerialNumber"
#endif // if !defined(CKM_ID2_MECHANISM_BASE)
PKCS#11 Interoperability with PIV cards
This section describes PKCS#11 features specific to PIV (Personal Identity Verification) cards supported by Personal Desktop.
Context value by card Issuer
Some card manufacturers provide special “context value” that can be used for key diversification. This value can be read using Personal Desktop's PKCS#11 API:
object = C_FindObjects(session, {{CKA_CLASS, CKO_DATA},
{CKA_LABEL, "context value"}});
context_value = C_GetAttributeValue(session, object, CKA_VALUE);
PIN mapping
There are 3 types of PIN supported by the C_Login
function. They are mapped to PIV authentication objects in the following ways:
PKCS#11 PIN | PIV authentication object |
---|---|
| PIV PIN |
| PIV Management Key |
| PIV PUK |
PINs that aren't UTF-8 strings must be encoded in a Data URI, see “PIN Data URI”.
Key generation
After calling C_GenerateKeyPair
, the public key is stored in Personal Desktop's memory until the application is closed or the card is removed. The public key is not written to the card because PIV cards do not have containers for public keys. The calling application must save the public key elsewhere for issuing the certificate.