python Thread中的pkcs11

时间:2016-08-01 20:23:18

标签: multiprocessing ctypes smartcard pkcs#11 opensc

从单个python线程中,如下所示,我收到错误“请在任何插槽中插入令牌”,它似乎看不到我的令牌。我将代码更改为不从多处理线程内部运行并且它可以正常工作。为了将PyKCS11库从等式中取出,我还使用ctypes进行了测试并包装了opensc中实现的标准pkcs11函数,除了从python Thread运行时,我仍遇到同样的问题。会导致这种情况的原因是什么?

在python中使用pkcs11线程失败:

from PyKCS11 import LowLevel
import sys
from multiprocessing import Thread


class MyThread(Thread):
    def run(self):
        lib = "/usr/local/lib/opensc-pkcs11.so" # place here your PKCS#11 library
        pin = "12345678" # place here the pin of your token

        a = LowLevel.CPKCS11Lib()
        info = LowLevel.CK_INFO()
        slotList = LowLevel.ckintlist()

        loadRes = a.Load(lib, 1)
        print "Load of library '%s' : %s " % (lib, str(loadRes) )
        if not loadRes: 
            sys.exit(1)
        print "C_GetInfo: rv=" , hex(a.C_GetInfo(info))
        print "Library manufacturerID: ", info.GetManufacturerID()
        # listing only slots with a token inside.
        rv = a.C_GetSlotList(1, slotList)
        if (rv != LowLevel.CKR_OK): 
            sys.exit(1)
        if len(slotList) == 0:
            print "Please insert a token in any slot"
            sys.exit(1)


mythread = MyThread()
mythread.start()
mythread.join()

在线程之外使用pkcs11:

from PyKCS11 import LowLevel
import sys

def run(self):
        lib = "/usr/local/lib/opensc-pkcs11.so" # place here your PKCS#11 library
        pin = "12345678" # place here the pin of your token

        a = LowLevel.CPKCS11Lib()
        info = LowLevel.CK_INFO()
        slotList = LowLevel.ckintlist()

        loadRes = a.Load(lib, 1)
        print "Load of library '%s' : %s " % (lib, str(loadRes) )
        if not loadRes: 
            sys.exit(1)
        print "C_GetInfo: rv=" , hex(a.C_GetInfo(info))
        print "Library manufacturerID: ", info.GetManufacturerID()
        # listing only slots with a token inside.
        rv = a.C_GetSlotList(1, slotList)
        if (rv != LowLevel.CKR_OK): 
            sys.exit(1)
        if len(slotList) == 0:
            print "Please insert a token in any slot"
            sys.exit(1)

run()

测试环境:

操作系统:OSX Yosemite

pkcs11中间件:opensc

1 个答案:

答案 0 :(得分:0)

有关多线程和PKCS#11库的更多信息,请参阅PKCS#11 v2.20规范的第6.6.2节:

  

6.6.2应用程序和线程

     

某些应用程序将以多线程方式访问Cryptoki库   时尚。 Cryptoki使应用程序能够提供信息   图书馆,以便他们可以给予适当的支持   多线程。特别是,当应用程序初始化a时   Cryptoki库调用C_Initialize,它可以指定其中一个   库的四种可能的多线程行为:

     
      
  1. 应用程序可以指定它不会从多个线程同时访问库,因此库需要   不用担心为了执行任何类型的锁定   线程安全。
  2.   
  3. 应用程序可以指定它将从多个线程同时访问库,并且库必须能够   使用本机操作系统同步原语来确保   适当的线程安全行为。
  4.   
  5. 应用程序可以指定它将从多个线程同时访问库,并且库必须使用一组   应用程序提供的同步原语以确保正确   线程安全的行为。
  6.   
  7. 应用程序可以指定它将从多个线程同时访问库,并且库必须使用其中一个   本机操作系统同步原语或一组   应用程序提供的同步原语以确保正确   线程安全的行为。
  8.   

IMO是多线程应用程序中最常用的类型是第二种类型。要激活它,您需要将CKF_OS_LOCKING_OK标记传递给C_Initialize函数。以下代码显示了如何使用Pkcs11Interop库在C#中实现此目的:

Pkcs11 pkcs11 = new Pkcs11(libraryPath);

CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
initArgs.Flags = CKF.CKF_OS_LOCKING_OK;

CKR rv = pkcs11.C_Initialize(initArgs);
if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
    throw new Pkcs11Exception("C_Initialize", rv);

我相信你需要在Python中使用类似的代码。只是在这里猜测,但也许你需要将一些参数传递给LowLevel.CPKCS11Lib()