Python PKCS11发动机不工作';t在引擎清理后注销()
我想做以下工作:Python PKCS11发动机不工作';t在引擎清理后注销(),python,logout,m2crypto,pkcs#11,Python,Logout,M2crypto,Pkcs#11,我想做以下工作: 在安全令牌上生成密钥对(我使用阿拉丁令牌)(PyKCS11) 生成PKCS#10请求(我使用M2Crypto+引擎#pkcs11)并将其发送给CA 从CA接收签名的X.509证书并将其写入安全令牌 请求生成如下所示: def生成请求( self,uid,cn=None,user\u pin=None,keyid=TOKEN\u TEMP\u KEY\u ID): “”“生成PKCS#10证书请求” @param keyid:用于生成证书请求的密钥的ID @类型keyid:str
def生成请求(
self,uid,cn=None,user\u pin=None,keyid=TOKEN\u TEMP\u KEY\u ID):
“”“生成PKCS#10证书请求”
@param keyid:用于生成证书请求的密钥的ID
@类型keyid:str
@param uid:要放入请求主题可分辨名称的uid
@类型uid:str
@参数cn:用于证书的主体的通用名称(如有)
请求生成
@cn型:str
@param user_pin:用户pin码。用户权限是必需的
签署证书申请
@输入用户密码:str
@返回由令牌私钥签名的PEM格式的PKCS10请求
"""
发动机负载动力()
e=引擎。引擎(“动态”)
e、 ctrl\u cmd\u字符串('SO\u路径',PKCS11\u引擎\u路径)
e、 ctrl\u cmd\u字符串('LIST\u ADD','1')
e、 ctrl\u cmd\u字符串(“加载”,无)
e、 ctrl\u cmd\u字符串('MODULE\u PATH',PKCS11\u LIBRARY\u PATH)
a=引擎。引擎('pkcs11')
a、 init()
#应向该函数提供十六进制编码的密钥id
k=a.load\u private\u key(hexlify(keyid),pin=user\u pin)
req=X509.Request()
subject_name=PKCS10_DN_PREFIX+('UID',MBSTRING_ASC,UID,-1,-1,0),)
如果cn:
subject_name=subject_name+(('CN',MBSTRING_ASC,CN,-1,-1),)
name=X509.X509_name()
对于主题名称中的条目:
name.add_entry_by_txt(*entry)
要求设置主题(名称)
要求设置公开密钥(k)
要求符号(k,‘sha1’)
reqpem=需求as_pem()
Engine.cleanup()
返回请求
以下是将证书写入安全令牌的代码:
def write_证书(self、cert_pem、so_pin):
“”“将证书写入令牌”
@param cert_pem:pem格式的证书
@类型cert\u pem:str
@param so_pin:安全官员的pin码
@输入so_pin:str
"""
证书=X509。加载证书字符串(证书pem)
如果证书检查_ca():#使用什么标签?
标签=令牌\u证书\u标签
其他:
标签=令牌\用户\证书\标签
tCert=(
(PyKCS11.LowLevel.CKA_类,PyKCS11.LowLevel.CKO_证书),
(PyKCS11.LowLevel.CKA_证书类型,PyKCS11.LowLevel.CKC_X_509),
(PyKCS11.LowLevel.CKA_标记,True),
(PyKCS11.LowLevel.CKA_PRIVATE,False),
(PyKCS11.LowLevel.CKA_标签,标签),
(PyKCS11.LowLevel.CKA_ID,make_key_ID(cert.get_pubkey()),
(PyKCS11.LowLevel.CKA_SUBJECT,cert.get_SUBJECT().as_der()),
(PyKCS11.LowLevel.CKA_ISSUER,cert.get_ISSUER().as_der()),
(PyKCS11.LowLevel.CKA_序列号,证书获取序列号()),
(PyKCS11.LowLevel.CKA_值,证书as_der())
s=self.lib.openSession(self.slot,PyKCS11.CKF_RW_SESSION)
s、 登录(so_pin,PyKCS11.LowLevel.CKU_so)
s、 createObject(tCert)
s、 注销()
s、 关闭会话()
问题是,在生成请求之后,我得到了CKR\u用户\u另一个\u已经\u登录错误。我查看了engine_pkcs11源代码和engine_pkcs11.c(https://github.com/OpenSC/engine_pkcs11/blob/master/src/engine_pkcs11.c)文件中有一个函数名为静态EVP\u PKEY*pkcs11\u load\u key
。它很长,所以这里是它的一部分:
/*现在使用(可能为空)pin登录*/
if(PKCS11_登录(插槽,0,pin)){
/*登录失败,因此释放PIN(如果存在)*/
如果(pin!=NULL){
OPENSSL_清理(引脚、引脚长度);
免费(pin);
pin=NULL;
引脚长度=0;
}
失败(“登录失败\n”);
}
所以,据我所知,登录是在使用密钥时执行的(PKCS#10请求生成需要密钥)。如果执行了登录,那么我认为也应该执行相应的注销,但我找不到。以下是ENGINE_finish()函数的源代码:
int pkcs11_完成(发动机*发动机)
{
如果(ctx){
PKCS11_CTX_卸载(CTX);
PKCS11_CTX_免费(CTX);
ctx=NULL;
}
如果(pin!=NULL){
OPENSSL_清理(引脚、引脚长度);
免费(pin);
pin=NULL;
引脚长度=0;
}
返回1;
}
是否可以在第2步以某种方式(可能隐式地)从安全令牌注销?最后,我可以这样做: 在加载引擎之前,我打开新会话并登录到它 完成工作后,我关闭会话(仅使用closeSession()是不够的) 所以请求生成是这样完成的
s = self.lib.openSession(self.slot, PyKCS11.CKF_RW_SESSION)
s.login(user_pin)
Engine.load_dynamic()
。。。
我在引擎清理后加了一句
a.finish()
Engine.cleanup()
s.logout()
s.closeAllSessions()
我还必须对PyKCS11源代码中的会话类进行一些修补,因为有一个输入错误(closeAllSession而不是closeAllSessions):
希望这有帮助
def closeAllSessions(self):
"""
C_CloseAllSessions
"""
rv = self.lib.C_CloseAllSessions(self.slot)
if rv != CKR_OK:
raise PyKCS11Error(rv)