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

new(p1 = v1, p2 = v2) click to toggle source
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;
}
new(so_path=nil, args={}) click to toggle source

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
Also aliased as: unwrapped_initialize

Public Instance Methods

C_Finalize() click to toggle source

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;
}
C_GetFunctionList() click to toggle source

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;
}
C_GetInfo() click to toggle source

Returns general information about Cryptoki. @return [CK_INFO]

# File lib/pkcs11/library.rb, line 63
def C_GetInfo
  unwrapped_C_GetInfo
end
Also aliased as: unwrapped_C_GetInfo, info
C_GetSlotList(tokenPresent=false) click to toggle source

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
Also aliased as: unwrapped_C_GetSlotList, slots
C_Initialize() click to toggle source

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;
}
Also aliased as: unwrapped_C_Initialize
C_WaitForSlotEvent(flags=0) click to toggle source

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
active_slots() click to toggle source

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
all_slots() click to toggle source

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
close() click to toggle source

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
info()
Alias for: C_GetInfo
load_library() click to toggle source

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;
}
slots(tokenPresent=false)
Alias for: C_GetSlotList
unload_library() click to toggle source

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;
}
unwrapped_C_Initialize()
Alias for: C_Initialize
unwrapped_C_WaitForSlotEvent(flags=0)
Alias for: C_WaitForSlotEvent
vendor_all_attribute_names() click to toggle source

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
vendor_class_CK_ATTRIBUTE() click to toggle source

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;
}
vendor_const_get(name) click to toggle source

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
vendor_mechanism_parameter_struct(mech) click to toggle source

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
vendor_raise_on_return_value(p1) click to toggle source

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;
}
wait_for_slot_event(flags=0)
Alias for: C_WaitForSlotEvent

Private Instance Methods

unwrapped_C_GetInfo()
Alias for: C_GetInfo
unwrapped_C_GetSlotList(tokenPresent=false)
Alias for: C_GetSlotList
unwrapped_initialize(so_path=nil, args={})

@private

Alias for: new