You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »


PKCS#11 is the standardization of a platform independant API for cryptographic tokens – in short "cryptoki" which stands for cryptographic token interface. Whenever we speak of cryptoki we use it as a synonym and mean the specification (see [CRTK04]) of the standard (other documents often mean the API).
On a physical abstraction level the standard is located almost on the top of the layers. Figure 1 shows how cryptoki is integrated in our environment. The standard itself does not define what kind of security token is used. Our implementation of cryptoki exclusively accesses smartcards as shown in Figure 1.
Cryptoki has the goal to simplify the access of cryptographic hardware. Once developers have integrated the API and use it within their applications they can switch the middleware to a different PKCS#11 implementation and use the dedicated security token without chaning any line of code as far as both security tokens offer the same features and do not have distinct special behaviours.
Before we list our supported parts of cryptoki (see chapter 2) we first want you to get familiar with some basic cryptoki principles. Developers who already got in contact with PKCS#11 can go on with reading the next chapter but are also invited to read the introduction parts.

Basic principles of PKCS#11

We already learned that the cryptoki API can be universally used with different implementations for accessing different security tokens. In order to support this diversity some basics processes and features need to be specified. Within this part we specify those principles and show some of the most important workflows. Lets start with some basic notations.

Slot

Cryptoki supports multislot architecture where our implementation uses slots to identify smartcard readers. More generalized a slot can be seen as a hardware element having a security token inserted or not. Each slot has a unique ID which does not change as long as cryptoki is once initialized.

The slot ID will never change during the runtime of your application. Other applications could have different slot IDs - all IDs (not only slot IDs) are always context specific i.e. they are only valid for your application!

Slot-Info

Each slot has its own slot-info containing some details like manufacturer information, slotname and so on..

Slot-Events

As recently mentioned a slot will not always contain a token. As a matter of fact slots can be tagged as non removable (you can find this information in the slot info) i.e. that the security token – e.g. a smartcard cannot be removed because its solderd into the smartcard reader. All slots being tagged as removable should support slot-events. Slot-events give information about the reader state i.e. for example that a smartcard was inserted or removed.

Token

A Token can be seen as the piece of hardware
in fact a token is not always hardware – there could be software token implementations as well, e.g. a cryptograhic software keystore. Someone could also implement cryptoki in order to access those software elements. supporting the desired cryptographic features. It's bound to the Slot ID which means that there is no own instance and it has no ID itself. Whenever you want to access the token you are just doing it virtually by accessing the Slot. Since a token can be removed / inserted there is the opportunity to get detailed information about it in order to e.g. avoid mix ups with other tokens.

Token-Info

Similar to the slot-info the token-info contains information about the manufacturer, model and so on. Furthermore this structure contains information about the tokens serial (for us – the serial number of the smartcard), available space, specific flags, etc. For us the flags are besides the smart cards serial the most valuable information since they contain e.g. if the smartcard is locked due to too many invalid PIN retries.

Mechanism

As we mentioned earlier tokens can be – if tagged so – removed from the slot and even replaced by another one. Supported cryptographic features may vary between the tokens since applets can be easily replaced by offering new features. In a cryptoki specific context those supported features are called mechanisms. Since we do not want to implement another PKCS#11 for each released applet version cryptoki adds the support of dynamically reading the supported mechanisms of the currently inserted token. Mechanisms are splitted in eight different functionalities where we subclassed them to six different types

  • Digests
    • Digest
  • Ciphers
    • Encrypt / Decrypt,
    • Wrap / Unwrap
  • Signatures
    • Sign / Verify
    • Sign Recover / Verify Recover
  • KeyGenerators
    • Generate Key
  • KeyPairGenerators
    • Generate KeyPair
  • KeyDerivers
    • Derive

You can find our version-specific support of mechanisms in Table 2. A mechanism is identified by a pre-defined PKCS#11 ID. A token supporting a specific mechanism can further be asked for more details – called the mechanism-info.

Mechanism-Info

The mechanism-info gives information about the mechanism-class (in form of boolean values – isEncrypt, isDecrypt, …) and the token-specific supported key- or digests output-sizes.

Session

In order to access the tokens objects or to actively use its mechanisms a session needs to be opened. During a "normal" session – also known as public session – only temporary objects can be created. They are existent as long as the session is not closed or the token is removed and are visible for all other open sessions created for this token. The keyword "normal" already implies that there are several session-states – so lets have a look at these and their limitations.

Session-state

The session-state limits the visibility of the token's objects and manages its access rights e.g. whether an object can be persistently written to the smartcard. We distinguish the following states:

  1. Public read mode

In public read mode we can create / destroy temporary public non token objects – also called public session objects. Furthermore we can see all objects on the token which are tagged as public.

  1. Public read / write mode

In this mode we have the same features as in the previous mode. Furthermore we can persistently write public objects to the card such as a certificate, a public data object or a public key. We also can destroy those objects.

The applet installed on our smartcards supports the import of public keys BUT does not support internal calculations with them. This has the following reason:
Whenever a keypair (public / private key) is imported or generated the necessary information for doing cryptographical calculations is completely stored within the private key record. A public key record will be also written but this is just for completeness. On APDU level whether doing a public (encrypt / verify) or a private (decrypt / sign) calculation always needs the private key to be selected!
It is possible to store a single public key in a public key record BUT the applet will not be able to use it to encrypt or verify data. In order to support those calculations for single public keys or session objects (session objects are not stored on the token resulting in not being able to use the cards cryptographic processing unit) we offer this in software.

  1. User read mode

In this mode we have the same options as in the first mode. Furthermore we can read the private objects stored on the token and access them for cryptographic operations. Additionally we can create and destroy private session objects.

  1. User read / write mode

In this mode we have the same options as in the previous mode. Furthermore we have full access to create and destroy objects on the token. This mode is necessary to import or generate keypairs, secret keys or private data objects

  1. SO mode

In this mode we have the same options as in the first mode. Furthermore we can set (reset) the users PIN and install public root certificates (by tagging them with TRUSTED – this is not supported yet). We do NOT have any access to private objects but can create and destroy public token objects.

  • In order to create a user read session, create a public read session and log in as user.
  • In order to create a user read / write session, create a public read / write session and log in as user.
  • In order to create a SO session, create a public read / write session and log in as SO.

See Figure 2 for visualization.

The mix-up of sessions having different session states is very limited:

  1. When a user session exists no SO session can be created and vice versa
  2. As soon as a session switches to user mode all open sessions switch to user mode
  • When a SO session exists no user session can be established due to 1.
  1. A SO session can not be created out of a read session
  2. As soon as a session switches to SO mode all open sessions switch to SO mode.
  • When a user session exists SO mode can NOT be established due to 1.
  • When a read session exists (and even no user is logged in) SO mode can NOT be established due to 3.


Figure 2: session states

Session objects

As we see objects stored on the token are accessible in different ways whereas session objects can be always created / destroyed creating private session objects is still limited to user mode!.

A session object lives as long as its origin session stays alive and is accessible by all other sessions accessing that slot in an application specific context - other applications may have their own session objects but do not have any access to foreign application specific created session objects.. Other slot specific sessions are also allowed to destroy a session object even when they do not have created it!

During a public session only public session objects can be created / destroyed
During a user session public and private session objects can be created / destroyed

  • private session objects are never visible for public sessions since only user sessions can create private session objects and whenever a user is logged in all open sessions are converted to user sessions and are no more public.

Token Object

Contrary to session objects token objects are persistent and accessible to all applications we previously learned that session objects are only valid in an application specifc context. When one application creates a token object all other applications using cryptoki may need to close all sessions and open one session again in order to detect a new token object.. Visibility and access rights are described in 1.1.4 (Session state). According to one object's type, objects are stored in different rom sections. We currently support to write the following types:

  • Up to 32 private keys (RSA & EC)
  • Up to 32 public keys (RSA & EC)
  • Up to 255 certifcates the applet supports up to 255 certificate entries. Due to variable certificate lengths the amount of entries varies and could be even less than this value. (X509)
  • Up to 255 data objects the same as mentioned in 7 applies for data objects

In order to create a token object the "Token"-flag needs to be set to "true". For more information see 3.1.4 (Token). Otherwise a session object is created. Lets have a look at the supported types.

Key

A key can either be a secret-, a private- or a public key. The latter one needs not to be stored securely despite the others since their data is quite sensible. The smartcard's storage is exclusively separated for all these kind of keys where secret- and private keys are written to tamper resistant memory i.e. once created they will never leave the card. Public keys are written to simpler (and even cheaper) memory in fact public keys are just written for completeness since they are also stored within the private key storage. See 1.1.4 Session state #2 for more information..
In order to distinguish those types the attributes "ClassType" and "KeyType" shall necessarily be written. For more information regarding these attributes see 3.1.4.

Certificate

Certificates are also stored in an own data section where we differ between trusted certificates and normal ones. Currently we only support the import of normal ones whenever we speak of certificates we mean x509 certificates. Trusted certificates have their own data section which is more secure than the normal rom storage.
Trusted certificates need a present "Trusted" attribute tagged with "true" where normal certificates do not have that attribute or are tagged with "false". This feature is not implemented yet.

Data

Data objects can either be stored as private or public. Private data objects can only be written or destroyed in user write sessions and just appear for user sessions. Public data objects are always visible and destroyable during write sessions.

Workflows / Using cryptoki

So far we've learned some PKCS#11 basics and are ready to exercise some workflows. As we already know we need a user read / write session in order to write private objects and at least a public read / write session to write public objects to the token. This small example tells us how to initialize the library and create a user read / write session. More information about e.g. how to gernerate or to import a keypair can be read in 3 and 5.
Before we can initialize the library we have to receive the PKCS#11 function addresses. This is done by calling C_GetFunctionList using an instance of CK_FUNCTION_LIST_PTR as parameter. After C_GetFunctionList returns successfully we can use the CK_FUNCTION_LIST_PTR for calling the PKCS#11 defined functions.
First we have to initialize the library by using the CK_FUNCTION_LIST_PTR to call C_Initialize. For this call we use NULL as parameter. The library then starts to communicate with the SCARD interface (also known as PCSC-lite) and retrieves all available smartcard information from the OS.
Now we have to call C_GetSlotList in order to get the available smartcard readers and their IDs. We can use CK_TRUE as first parameter in order to receive all slots having a smartcard inserted.
After receiving a valid slot having a token / smartcard inserted we can use its ID to create a session. For creating a session we call C_OpenSession having one previously received slotID and CKF_SERIAL_SESSION | CKF_RW_SESSION as two of the five parameters.

For our implementation it is mandatory to call C_OpenSession with CKF_SERIAL_SESSION


Now we are ready to change the session state from public read write to user read write by calling C_Login. Then we are ready for creating / destroying token objects or using the smartcards crypto functionality like encrypt decrypt can even be called in public mode when using public key cryptography.
We can revert all these steps by calling the following functions in the specified order:

  • C_Logout to revert the user session back to a public session created private session objects will be destroyed, private token objects are no longer accessible. Other slot / token specific private sessions are also downgraded to public sessions.
  • C_CloseSession to destroy the session and all it's origin session objects created token objects stay persistent
  • C_Finalize when cryptoki is not used anymore
  • No labels