使用HSM(使用PKCS11标准API)生成自签名证书报告“包装密钥句柄无效”错误(错误代码113 , CKR_WRAPPING_KEY_HANDLE_INVALID )。 当使用GUI ctbrowser工具生成或使用与其演示类似的代码时,会发生这种情况。
下面是重现问题的代码示例,它生成RSA密钥对,然后尝试使用它们生成自签名证书。
int main() { int rv; CK_CHAR pwd[] = "password"; static char pubkeyLabel[256]="demoPub"; static char prvkeyLabel[256]="demoPrv"; static CK_BYTE id[256]; static CK_BBOOL isTok = TRUE; static CK_BBOOL True = TRUE; static CK_BBOOL False = FALSE; CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hPubKey; CK_OBJECT_HANDLE_PTR phPubKey = &hPubKey; CK_OBJECT_HANDLE hSignerKey; CK_OBJECT_HANDLE_PTR phSignerKey = &hSignerKey; CK_OBJECT_HANDLE hCert; CK_OBJECT_HANDLE_PTR phCert = &hCert; CK_MECHANISM mechanism = { 0, NULL, 0 }; static CK_SIZE mBits=2048; static char edate[] = {'2','0','2','0','1','2','3','1'}; static char certLabel[128]="demo_cert"; static char subject[256]="C=XX,ST=XX,L=XX,O=MEOW,OU=HSM,CN=TESTCERT"; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_TOKEN, &isTok, 1}, {CKA_PRIVATE, &False, 1}, {CKA_LABEL, pubkeyLabel, sizeof(pubkeyLabel)}, {CKA_SUBJECT_STR, subject, sizeof(subject)}, {CKA_MODULUS_BITS, &mBits, sizeof(mBits)}, {CKA_ENCRYPT, &False, 1}, {CKA_VERIFY, &True, 1}, {CKA_WRAP, &False, 1}, {CKA_DERIVE, &True, 1}, {CKA_EXTRACTABLE, &True, 1}, {CKA_EXPORTABLE, &True, 1} }; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_TOKEN, &isTok, 1}, {CKA_LABEL, prvkeyLabel, sizeof(prvkeyLabel)}, {CKA_PRIVATE, &True, 1}, {CKA_SUBJECT_STR, subject, sizeof(subject)}, {CKA_ID, id, sizeof(id)}, {CKA_SENSITIVE, &True, 1}, {CKA_DECRYPT, &False, 1}, {CKA_SIGN, &True, 1}, {CKA_UNWRAP, &True, 1}, {CKA_WRAP, &False, 1}, {CKA_EXTRACTABLE, &False, 1}, {CKA_EXPORTABLE, &False, 1} }; CK_ATTRIBUTE certTemplate[] = { {CKA_TOKEN, &True, 1}, {CKA_PRIVATE, &False, 1}, {CKA_LABEL, certLabel, sizeof(certLabel)}, {CKA_SUBJECT_STR, subject, sizeof(subject)}, {CKA_ISSUER_STR, subject, sizeof(subject)}, {CKA_END_DATE, edate, sizeof(edate)}, {CKA_EXTRACTABLE, &True, 1}, {CKA_EXPORTABLE, &True, 1} }; printf("Generate cert %s from %s, signed by %s.\n", certLabel, pubkeyLabel, prvkeyLabel); rv = C_Initialize(NULL_PTR); if ( rv ) return rv; rv = C_OpenSession(0, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL, NULL, &hSession); rv = C_Login(hSession, CKU_USER, pwd, 8); publicKeyTemplate[2].valueLen = (CK_SIZE)strlen((char*)pubkeyLabel); publicKeyTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1; privateKeyTemplate[1].valueLen = (CK_SIZE)strlen((char*)prvkeyLabel); privateKeyTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1; mechanism.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; rv = C_GenerateKeyPair(hSession, &mechanism, publicKeyTemplate, NUMITEMS(publicKeyTemplate), privateKeyTemplate, NUMITEMS(privateKeyTemplate), phPubKey, phSignerKey); printf("Keypair generated with rv=%x\n", rv); mechanism.mechanism = CKM_SHA256_RSA_PKCS; rv = C_SignInit(hSession, &mechanism, hSignerKey); printf("cert signer initiated with rv=%x\n", rv); mechanism.mechanism = CKM_ENCODE_X_509; certTemplate[2].valueLen = (CK_SIZE)strlen((char*)certLabel); certTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1; certTemplate[4].valueLen = (CK_SIZE)strlen((char*)subject)+1; rv = C_DeriveKey(hSession, &mechanism, hPubKey, certTemplate, NUMITEMS(certTemplate), phCert); printf("cert generation finished with rv=%x\n", rv); return 0; }由于整个过程不涉及任何包装,我不知道如何调试它。 有没有人知道它有什么问题? (注意:插槽已预先存在并已初始化。)
Using HSM (with PKCS11 standard API) to generate self-signed cert reports "wrapping key handle invalid" error (Error Code 113, CKR_WRAPPING_KEY_HANDLE_INVALID). This happens both when using GUI ctbrowser tool to generate or using code similar to their demo.
Here is a code example to reproduce the issue, it generate a RSA keypair and then attempt to generate a self-signed cert with them.
int main() { int rv; CK_CHAR pwd[] = "password"; static char pubkeyLabel[256]="demoPub"; static char prvkeyLabel[256]="demoPrv"; static CK_BYTE id[256]; static CK_BBOOL isTok = TRUE; static CK_BBOOL True = TRUE; static CK_BBOOL False = FALSE; CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hPubKey; CK_OBJECT_HANDLE_PTR phPubKey = &hPubKey; CK_OBJECT_HANDLE hSignerKey; CK_OBJECT_HANDLE_PTR phSignerKey = &hSignerKey; CK_OBJECT_HANDLE hCert; CK_OBJECT_HANDLE_PTR phCert = &hCert; CK_MECHANISM mechanism = { 0, NULL, 0 }; static CK_SIZE mBits=2048; static char edate[] = {'2','0','2','0','1','2','3','1'}; static char certLabel[128]="demo_cert"; static char subject[256]="C=XX,ST=XX,L=XX,O=MEOW,OU=HSM,CN=TESTCERT"; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_TOKEN, &isTok, 1}, {CKA_PRIVATE, &False, 1}, {CKA_LABEL, pubkeyLabel, sizeof(pubkeyLabel)}, {CKA_SUBJECT_STR, subject, sizeof(subject)}, {CKA_MODULUS_BITS, &mBits, sizeof(mBits)}, {CKA_ENCRYPT, &False, 1}, {CKA_VERIFY, &True, 1}, {CKA_WRAP, &False, 1}, {CKA_DERIVE, &True, 1}, {CKA_EXTRACTABLE, &True, 1}, {CKA_EXPORTABLE, &True, 1} }; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_TOKEN, &isTok, 1}, {CKA_LABEL, prvkeyLabel, sizeof(prvkeyLabel)}, {CKA_PRIVATE, &True, 1}, {CKA_SUBJECT_STR, subject, sizeof(subject)}, {CKA_ID, id, sizeof(id)}, {CKA_SENSITIVE, &True, 1}, {CKA_DECRYPT, &False, 1}, {CKA_SIGN, &True, 1}, {CKA_UNWRAP, &True, 1}, {CKA_WRAP, &False, 1}, {CKA_EXTRACTABLE, &False, 1}, {CKA_EXPORTABLE, &False, 1} }; CK_ATTRIBUTE certTemplate[] = { {CKA_TOKEN, &True, 1}, {CKA_PRIVATE, &False, 1}, {CKA_LABEL, certLabel, sizeof(certLabel)}, {CKA_SUBJECT_STR, subject, sizeof(subject)}, {CKA_ISSUER_STR, subject, sizeof(subject)}, {CKA_END_DATE, edate, sizeof(edate)}, {CKA_EXTRACTABLE, &True, 1}, {CKA_EXPORTABLE, &True, 1} }; printf("Generate cert %s from %s, signed by %s.\n", certLabel, pubkeyLabel, prvkeyLabel); rv = C_Initialize(NULL_PTR); if ( rv ) return rv; rv = C_OpenSession(0, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL, NULL, &hSession); rv = C_Login(hSession, CKU_USER, pwd, 8); publicKeyTemplate[2].valueLen = (CK_SIZE)strlen((char*)pubkeyLabel); publicKeyTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1; privateKeyTemplate[1].valueLen = (CK_SIZE)strlen((char*)prvkeyLabel); privateKeyTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1; mechanism.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; rv = C_GenerateKeyPair(hSession, &mechanism, publicKeyTemplate, NUMITEMS(publicKeyTemplate), privateKeyTemplate, NUMITEMS(privateKeyTemplate), phPubKey, phSignerKey); printf("Keypair generated with rv=%x\n", rv); mechanism.mechanism = CKM_SHA256_RSA_PKCS; rv = C_SignInit(hSession, &mechanism, hSignerKey); printf("cert signer initiated with rv=%x\n", rv); mechanism.mechanism = CKM_ENCODE_X_509; certTemplate[2].valueLen = (CK_SIZE)strlen((char*)certLabel); certTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1; certTemplate[4].valueLen = (CK_SIZE)strlen((char*)subject)+1; rv = C_DeriveKey(hSession, &mechanism, hPubKey, certTemplate, NUMITEMS(certTemplate), phCert); printf("cert generation finished with rv=%x\n", rv); return 0; }Since the entire process do not involve any wrapping, I have no clue on how to debug this. Does anyone has any idea what's wrong with it? (NOTE: slot is pre-existing and initialized.)
最满意答案
问题是由于缺少CKA_SERIAL_NUMBER ,根据受版权保护的PKCS11 API指南(ProtectToolkit C程序员手册,版权所有©Eracom Technologies),当未提供序列号时,将返回错误CKR_WRAPPING_KEY_HANDLE_INVALID 。
因此,要么在签名密钥中添加CKA_USAGE_COUNT ,要么通过在cert模板中指示CKA_SERIAL_NUMBER / CKA_SERIAL_NUMBER_INT来解决问题来指示证书的序列号。
The issue is caused by the lack of CKA_SERIAL_NUMBER, according to a copyrighted PKCS11 API guide (ProtectToolkit C Programmers Manual, Copyright © Eracom Technologies), when serial number is not provided, error CKR_WRAPPING_KEY_HANDLE_INVALID will be returned.
Hence either add a CKA_USAGE_COUNT to the signing key, or indicate the serial number for the cert by indicating CKA_SERIAL_NUMBER/CKA_SERIAL_NUMBER_INT in cert template would solve the issue.
更多推荐
发布评论