class PKCS11::Library
A Library
instance holds a handle to the opened PKCS#11 - dll or so file.
Low layer API¶ ↑
The API of the binding consists of a lower layer, which is near to the PKCS#11 C interface, and a higher layer, which is more Ruby like and more comfortable. The low layer is currently not explicitly documented and is not recommented to use.
All low layer PKCS#11 functions can be called on the {PKCS11::Library} object. Example for starting a session:
pkcs11 = PKCS11.open("/path/to/pkcs11.so") slot = pkcs11.C_GetSlotList(true).first session = pkcs11.C_OpenSession(slot, PKCS11::CKF_SERIAL_SESSION | PKCS11::CKF_RW_SESSION) pkcs11.C_Login(session, PKCS11::CKU_USER, "password")
The same on the high layer:
pkcs11 = PKCS11.open("/path/to/pkcs11.so") session = pkcs11.active_slots.first.open session.login(:USER, "password")
Public Class Methods
static VALUE pkcs11_initialize(int argc, VALUE *argv, VALUE self) { VALUE path, init_args; rb_scan_args(argc, argv, "02", &path, &init_args); if( !NIL_P(path) ){ rb_funcall(self, rb_intern("load_library"), 1, path); rb_funcall(self, rb_intern("C_GetFunctionList"), 0); rb_funcall2(self, rb_intern("C_Initialize"), 1, &init_args); } return self; }
Load and initialize a pkcs11 dynamic library.
@param [String, nil] so_path Path to the *.so or *.dll file to load. @param [Hash, CK_C_INITIALIZE_ARGS] args A Hash or CK_C_INITIALIZE_ARGS instance with load params.
If so_path is nil
no library is loaded or initialized. In this case the calls to {#load_library}, {#C_GetFunctionList} and {#C_Initialize} have to be done manually, before using other methods:
pkcs11 = PKCS11::Library.new pkcs11.load_library(so_path) pkcs11.C_GetFunctionList pkcs11.C_Initialize(args)
Note: When using RubyInstaller-2.4+ on Windows it might be required to add the path of dependent DLLs to the DLL search path. This can be done by the RUBY_DLL_PATH
environment variable. See github.com/oneclick/rubyinstaller2/wiki/For-gem-developers#user-content-dll-loading
# File lib/pkcs11/library.rb, line 41 def initialize(so_path=nil, args={}) unwrapped_initialize(so_path, args) end
Public Instance Methods
Is called to indicate that an application is finished with the Cryptoki library. @see PKCS11::Library#close
static VALUE pkcs11_C_Finalize(VALUE self) { CK_C_Finalize func; CK_RV rv; GetFunction(self, C_Finalize, func); CallFunction(C_Finalize, func, rv, NULL_PTR); if (rv != CKR_OK) pkcs11_raise(self,rv); return self; }
Obtains a pointer to the Cryptoki library's list of function pointers. The pointer is stored in the {PKCS11::Library} object and used to call any Cryptoki functions.
@see PKCS11::Library#initialize
static VALUE pkcs11_C_GetFunctionList(VALUE self) { pkcs11_ctx *ctx; CK_RV rv; CK_C_GetFunctionList func; Data_Get_Struct(self, pkcs11_ctx, ctx); #ifdef compile_for_windows func = (CK_C_GetFunctionList)GetProcAddress(ctx->module, "C_GetFunctionList"); if(!func){ char error_text[999] = "GetProcAddress() error"; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&error_text, sizeof(error_text), NULL); rb_raise(ePKCS11Error, "%s", error_text); } #else func = (CK_C_GetFunctionList)dlsym(ctx->module, "C_GetFunctionList"); if(!func) rb_raise(ePKCS11Error, "%s", dlerror()); #endif CallFunction(C_GetFunctionList, func, rv, &(ctx->functions)); if (rv != CKR_OK) pkcs11_raise(self,rv); return self; }
Returns general information about Cryptoki. @return [CK_INFO]
# File lib/pkcs11/library.rb, line 63 def C_GetInfo unwrapped_C_GetInfo end
Obtain an array of Slot
objects in the system.
@param [true, false] tokenPresent indicates whether the list
obtained includes only those slots with a token present (true), or all slots (false);
@return [Array<Slot>]
# File lib/pkcs11/library.rb, line 76 def C_GetSlotList(tokenPresent=false) slots = unwrapped_C_GetSlotList(tokenPresent) slots.map{|slot| Slot.new self, slot } end
Initializes the Cryptoki library.
static VALUE pkcs11_C_Initialize(int argc, VALUE *argv, VALUE self) { VALUE init_args; CK_C_Initialize func; CK_C_INITIALIZE_ARGS *args; CK_RV rv; rb_scan_args(argc, argv, "01", &init_args); if (NIL_P(init_args)) args = NULL_PTR; else { if (!rb_obj_is_kind_of(init_args, cCK_C_INITIALIZE_ARGS)) rb_raise(rb_eArgError, "2nd arg must be a PKCS11::CK_C_INITIALIZE_ARGS"); args = DATA_PTR(init_args); } GetFunction(self, C_Initialize, func); CallFunction(C_Initialize, func, rv, args); if (rv != CKR_OK) pkcs11_raise(self,rv); return self; }
Waits for a slot event, such as token insertion or token removal, to occur.
@param [Integer] flags determines whether or not the C_WaitForSlotEvent
call blocks (i.e., waits
for a slot event to occur); At present, the only flag defined for use in the flags argument is PKCS11::CKF_DONT_BLOCK
@return [Slot, nil] the slot that the event occurred in; nil if no event occured (CKR_NO_EVENT)
# File lib/pkcs11/library.rb, line 104 def C_WaitForSlotEvent(flags=0) slot = unwrapped_C_WaitForSlotEvent(flags) slot ? Slot.new(self, slot) : nil end
Obtain an array of Slot
objects in the system with a token present. @return [Array<Slot>]
# File lib/pkcs11/library.rb, line 86 def active_slots slots(true) end
Obtain an array of Slot
objects in the system regardless if a token is present. @return [Array<Slot>]
# File lib/pkcs11/library.rb, line 92 def all_slots slots(false) end
Finalize and unload the library. If not called explicit, the library is freed by the GC.
# File lib/pkcs11/library.rb, line 111 def close self.C_Finalize self.unload_library end
Load a Cryptoki library into process memory. @see PKCS11::Library#initialize
static VALUE pkcs11_load_library(VALUE self, VALUE path) { const char *so_path; pkcs11_ctx *ctx; so_path = StringValueCStr(path); Data_Get_Struct(self, pkcs11_ctx, ctx); #ifdef compile_for_windows if((ctx->module = LoadLibrary(so_path)) == NULL) { char error_text[999] = "LoadLibrary() error"; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&error_text, sizeof(error_text), NULL); rb_raise(ePKCS11Error, "%s", error_text); } #else if((ctx->module = dlopen(so_path, RTLD_NOW)) == NULL) { rb_raise(ePKCS11Error, "%s", dlerror()); } #endif return self; }
Unloads the Cryptoki library from process memory. @see PKCS11::Library#close
static VALUE pkcs11_unload_library(VALUE self) { pkcs11_ctx *ctx; Data_Get_Struct(self, pkcs11_ctx, ctx); pkcs11_ctx_unload_library(ctx); return self; }
Return an array of all known CKA_* attributes as String. This method could be overloaded for vendor specific extensions.
# File lib/pkcs11/library.rb, line 127 def vendor_all_attribute_names return ATTRIBUTES.values end
Return class CK_ATTRIBUTE
. This method can be overloaded to return a derived class that appropriate converts vendor specific attributes. @return [CK_ATTRIBUTE] some kind of CK_ATTRIBUTE
static VALUE pkcs11_vendor_class_CK_ATTRIBUTE(VALUE self) { return cCK_ATTRIBUTE; }
Return the value of a named constant. Used for CKA_* and CKM_* . This method could be overloaded for vendor specific extensions.
@param [String] name Name of the constant @return [Integer] Value of the constant
# File lib/pkcs11/library.rb, line 121 def vendor_const_get(name) PKCS11.const_get(name) end
Return the parameter struct of a given mechanism. This method could be overloaded for vendor specific extensions.
@param [Integer] mech Mechanism @return [PKCS11::CStruct] appropriate class as parameter for the mechanism
# File lib/pkcs11/library.rb, line 136 def vendor_mechanism_parameter_struct(mech) Helper::MechanismParameters[mech] end
Raise an exception for the given PKCS#11 return value. This method can be overloaded to raise vendor specific exceptions. It is only called for rv!=0 and it should never return regulary, but always by an exception. @param [Integer] rv return value of the latest operation
static VALUE pkcs11_vendor_raise_on_return_value(VALUE self, VALUE rv_value) { VALUE class; CK_RV rv = NUM2ULONG(rv_value); class = pkcs11_return_value_to_class(rv, ePKCS11Error); rb_raise(class, "%lu", rv); return Qnil; }