2017-01-12 9 views
1

Использование HSM (с стандартным API-интерфейсом PKCS11) для генерации самоподписанных отчетов сертификатов Ошибка «обертывание ключа недействительна» (код ошибки 113, CKR_WRAPPING_KEY_HANDLE_INVALID). Это происходит при использовании инструмента GUI ctbrowser для генерации или использования кода, аналогичного их демонстрации.HSM генерирует самоподписанный отчет о сертификате «ошибка переноса ключа недействительна»

Вот пример кода для воспроизведения проблемы, он генерирует пару ключей 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; 
} 

Поскольку весь процесс не связан с какой-либо упаковкой, я не знаю, как отладить это. Кто-нибудь знает, что с ним не так? (ПРИМЕЧАНИЕ: слот уже существует и инициализирован.)

+0

Я предлагаю вам связаться с производителем HSM и запросить поддержку. – SEJPM

+0

Вы устанавливаете много атрибутов явно, включая 'CKA_WRAP' и' CKA_UNWRAP', а также флаги EXTRACTABLE и EXPORTABLE (для которых может потребоваться ключ упаковки). Возможно, вам следует удалить эти атрибуты и повторить попытку. Если это сработает, вы можете снова установить их и посмотреть, какой из них вызывает сбой –

+0

@MaartenBodewes 'CKA_WRAP'' CKA_UNWRAP' являются атрибутами, их отключение означает, что они не будут использоваться в качестве ключей для экспорта других ключей. 'EXTRACTABLE' необходим для pubkey, иначе значение не может быть доступно, не говоря уже об экспорте (флаг EXPORTABLE) в cert. Я попробовал множество меньших атрибутов, это не сработало. – Chong

ответ

2

Проблема вызвана отсутствием CKA_SERIAL_NUMBER в соответствии с руководством по API PKCS11, защищенным авторским правом (Руководство по программированию ProtectToolkit C, Copyright © Eracom Technologies), когда серийный номер не является при условии, будет возвращена ошибка CKR_WRAPPING_KEY_HANDLE_INVALID.

Следовательно либо добавьте CKA_USAGE_COUNT к ключу подписи, либо укажите серийный номер для сертификата, указав CKA_SERIAL_NUMBER/CKA_SERIAL_NUMBER_INT в шаблоне cert, чтобы решить проблему.

+1

Эй, рад, что вы получили это решение, спасибо за сообщение на сайт. Извините, если мое предложение не сработало; это казалось чем-то, что могло быть неправильным. Я не могу вспомнить эту ошибку на HSM; странная, но хорошая информация. Вы можете принять свой собственный ответ через некоторое время (и я, конечно же, проголосовал). –

 Смежные вопросы

  • Нет связанных вопросов^_^