PKCS #11/Ruby Interface
- home
- API documentation
<img src=“https://travis-ci.com/larskanis/pkcs11.svg?branch=master” alt=“Build Status” /> <img src=“https://ci.appveyor.com/api/projects/status/8m7ugl1ogijw1c8c?svg=true” alt=“Build Status” />
This module allows Ruby programs to interface with “RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki)”. PKCS #11 is the de-facto standard to access cryptographic devices. You must have a PKCS #11 v2.x implementation library installed in order to use this module. Tested implementations of PKCS#11 librarys include:
-
OpenSC supported Smart Cards
-
Safenet - Protect Server and Luna HSMs
-
Mozilla_Soft_Token which comes with every firefox installation
This module works on Unix like operating systems and on Windows.
Installation
$ gem install pkcs11
This installs the PKCS#11 extension either by compiling (Unix) or by using the precompiled gem for Windows.
Usage
Cryptoki has a reputation to be complicated to implement and use. While this seems to be true for C, it shouldn’t for Ruby.
-
PKCS11.open opens a PKCS#11 Unix *.so file or Windows-DLL with a suitable PKCS #11 implementation and returns a PKCS11::Library.
-
PKCS11::Library#slots returns a list of PKCS11::Slot for all slots accessable by the library.
-
PKCS11::Slot#open opens a PKCS11::Session which is used for object handling and cryptographic operations.
-
PKCS11::Object represents a key, data or certificate object.
-
all constants defined in PKCS#11 v2.40 are available in the module PKCS11 and contain the associated Integer value (CKA_KEY_TYPE, CKK_AES, CKM_SHA_1 etc.)
-
also all PKCS#11 v2.40 structs are available in the module PKCS11 as proper ruby classes (PKCS11::CK_VERSION, PKCS11::CK_OTP_PARAMS etc.)
Example
require "rubygems"
require "pkcs11"
include PKCS11
pkcs11 = PKCS11.open("/path/to/pkcs11.so")
p pkcs11.info # => #<PKCS11::CK_INFO cryptokiVersion=...>
pkcs11.active_slots.first.open do |session|
session.login(:USER, "1234")
secret_key = session.generate_key(:DES2_KEY_GEN,
ENCRYPT: true, DECRYPT: true, SENSITIVE: true, TOKEN: true, LABEL: 'my key')
cryptogram = session.encrypt( {DES3_CBC_PAD: "\0"*8}, secret_key, "some plaintext")
session.logout
end
This opens a PKCS#11 library and prints it’s information block. Then a PKCS11::Session to the first active slot of the device is opened and a login is done on the user account. Now, a 112 bit DES3 key object is generated and some plaintext is encrypted with it. A 8-byte zero IV is used. In many cases method parameters can be Integer (like PKCS11::CKA_LABEL) or, as in the sample, Symbol (:LABEL) which is internally converted.
Many more usage examples can be found in the unit tests of the test
directory of the project or gem.
Detail information for the API specification is provided by the OASIS PKCS 11 Technical Committee. Please refer the URL: www.oasis-open.org/committees/tc_home.php?wg_abbrev=pkcs11
Browsable HTML can be found at www.cryptsoft.com/pkcs11doc.
Vendor extensions
Some vendors extend their libraries beyond the standard, in it’s own way. This can be used by vendor specific packages:
Threading
The pkcs11 binding fully supports background Ruby threads while calls to PKCS#11 functions.
According to the standard, calling the Cryptoki library from multiple threads simultaneously, requires to open it with flag PKCS11::CKF_OS_LOCKING_OK. Application-supplied synchronization primitives (CreateMutex, DestroyMutex, LockMutex, UnlockMutex) are not supported.
Compiling for Windows
The pkcs11 source gem can be built on Windows (with help of the RubyInstaller’s DevKit ) . Use
$ gem install pkcs11 --platform=ruby
for installation. In addition precompiled binary Windows gems are provided for convenience. They are installed by default on Windows.
The binary Windows gems can be compiled per rake-compiler-dock :
$ rake gem:windows
If everything works, there should be some files kind of pkcs11-VERSION-ARCH-mingw32.gem in the pkg directory for installation.
ToDo
-
support for proprietary extensions of other vendors
Development Status
Any operation that is possible with PKCS#11 in C, should be likewise possible in Ruby. Otherwise it is considered as a bug in the binding.
STATE FUNCTION NOTE
------ --------------------- ----------------------------------------
DONE C_Initialize
DONE C_Finalize
DONE C_GetInfo
DONE C_GetFunctionList
DONE C_GetSlotList
DONE C_GetSlotInfo
DONE C_GetTokenInfo
DONE C_GetMechanismList
DONE C_GetMechanismInfo
DONE C_InitToken
DONE C_InitPIN
DONE C_SetPIN
DONE C_OpenSession
DONE C_CloseSession
DONE C_CloseAllSessions
DONE C_GetSessionInfo
DONE C_GetOperationState
DONE C_SetOperationState
DONE C_Login
DONE C_Logout
DONE C_CreateObject
DONE C_CopyObject
DONE C_DestroyObject
DONE C_GetObjectSize
DONE C_GetAttributeValue
DONE C_SetAttributeValue
DONE C_FindObjectsInit
DONE C_FindObjects
DONE C_FindObjectsFinal
DONE C_EncryptInit
DONE C_Encrypt
DONE C_EncryptUpdate
DONE C_EncryptFinal
DONE C_DecryptInit
DONE C_Decrypt
DONE C_DecryptUpdate
DONE C_DecryptFinal
DONE C_DigestInit
DONE C_Digest
DONE C_DigestUpdate
DONE C_DigestKey
DONE C_DigestFinal
DONE C_SignInit
DONE C_Sign
DONE C_SignUpdate
DONE C_SignFinal
DONE C_SignRecoverInit
DONE C_SignRecover
DONE C_VerifyInit
DONE C_Verify
DONE C_VerifyUpdate
DONE C_VerifyFinal
DONE C_VerifyRecoverInit
DONE C_VerifyRecover
DONE C_DigestEncryptUpdate
DONE C_DecryptDigestUpdate
DONE C_SignEncryptUpdate
DONE C_DecryptVerifyUpdate
DONE C_GenerateKey
DONE C_GenerateKeyPair
DONE C_WrapKey
DONE C_UnwrapKey
DONE C_DeriveKey
DONE C_SeedRandom
DONE C_GenerateRandom
N/A C_GetFunctionStatus legacy function
N/A C_CancelFunction legacy function
DONE C_WaitForSlotEvent
Authors
-
Ryosuke Kutsuna <[email protected]>
-
GOTOU Yuuzou <[email protected]>
-
Lars Kanis <[email protected]>
-
Jonathan Patchell <[email protected]>
Copying
See MIT-LICENSE included in the package.