簡體   English   中英

使用pkcs#11從智能卡讀取文本文件

[英]Read text file from smart card with pkcs#11

我有一張空白的智能卡(SLE66CX322P, Cardos 4.3b)和一個讀卡器/寫卡器( Gemalto CT 40) 使用軟件,我可以初始化卡,生成密鑰,證書等。我還可以創建帶有一些文本的簡單ASCII文件,該文本將存儲在智能卡上。 我的問題是,如何使用pkcs#11 API讀取C/C++中此ASCII文件的內容?

這是到目前為止我嘗試過的(也使用Qt):

---------- cardreader.h ------------

#ifndef CARDREADER_H
#define CARDREADER_H

#include "cm-pkcs11.h"
#include <QCoreApplication>
#include <QObject>
#include <QtDebug>

class CardReader: public QObject
{
    Q_OBJECT

private:

    CK_RV rv;
    CK_ULONG slotCount;
    CK_SLOT_ID slotIds[10];
    CK_SLOT_ID slotId;
    CK_SESSION_HANDLE session;
    CK_TOKEN_INFO_PTR info;

    void readCard();

public:

    explicit CardReader(QObject *parent = 0);
};

#endif // CARDREADER_H

------- cardreader.cpp ----------

#include "cardreader.h"

CardReader::CardReader(QObject *parent) : QObject(parent)
{
    readCard();
}

/***********************************************************************/

void CardReader::readCard()
{
    rv = C_Initialize(NULL_PTR);

    slotCount = 10;
    rv = C_GetSlotList(CK_TRUE, slotIds, &slotCount);
    qWarning() << "Found" << slotCount << "slots";

    if (rv != CKR_OK || slotCount < 1)
    {
        qWarning() << "No slots found -> exit";
        return;
    }

    slotId = slotIds[0];

    rv = C_OpenSession(slotId, CKF_SERIAL_SESSION|CKF_RW_SESSION, NULL_PTR, NULL_PTR, &session);

    if (rv != CKR_OK)
    {
        qWarning() << "Sessions could not be opened -> exit";
        qWarning() << "RV (as hex value) = " << QString("%1").arg(rv, 0, 16);
        return;
    }

    /*********************************************************************/

    CK_OBJECT_CLASS dataClass = CKO_DATA;
    CK_OBJECT_HANDLE handleObject;
    CK_UTF8CHAR label[] = {"MyLabel"};
    CK_ULONG ulCount = 4ul;
    CK_CHAR application[] = {"TestApplication"};
    CK_BYTE dataValue[] = {"MyData"};
    CK_BBOOL valid = CK_TRUE;
    CK_ATTRIBUTE dataTemp[] =
    {
        {CKA_CLASS, &dataClass, sizeof(dataClass)},
        {CKA_VALUE, dataValue, sizeof(dataValue)},
        {CKA_LABEL, label, sizeof(label)-1},
        //{CKA_APPLICATION, application, sizeof(application)}
        {CKA_TOKEN, &valid, sizeof(true)}
    };

    rv = C_FindObjectsInit(session, dataTemp, 0);
    if (rv != CKR_OK)
    {
        qWarning() << "C_FindObjectsInit Error -> exit";
        qWarning() << "C_FindObjectsInit Error" << QString("%1").arg(rv, 0, 16);
        return;
    }


    while (1)
    {
        rv = C_FindObjects(session, &handleObject, 1, &ulCount);
        qWarning() << "C_FindObjects Result =" << QString("%1").arg(rv, 0, 16) << ", count =" << ulCount;
        if (rv != CKR_OK || ulCount == 0)
            break;

        rv = C_GetAttributeValue(session, handleObject, dataTemp, ulCount);

        if (rv != CKR_OK)
        {
            qWarning() << "C_GetAttributeValue error -> exit";
            qWarning() << "RV (as hex value) = " << QString("%1").arg(rv, 0, 16) << ", count = " << ulCount;
            return;
        }

        qWarning() << (const char *) dataTemp[0].pValue;
        qWarning() << (const char *) dataTemp[1].pValue;
        qWarning() << (const char *) dataTemp[2].pValue;
        qWarning() << (const char *) dataTemp[3].pValue;
    }
}

---------- main.cpp ----------

#include "cardreader.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CardReader c;

    return a.exec();
}

結果是塊

        qWarning() << (const char *) dataTemp[0].pValue;
        qWarning() << (const char *) dataTemp[1].pValue;
        qWarning() << (const char *) dataTemp[2].pValue;
        qWarning() << (const char *) dataTemp[3].pValue;

在控制台中打印了四次,但始終與MyLabelMyData一起打印,這是我在CardReader::readCard()開頭指定的結果。 智能卡上的文本文件的內容當然有所不同,但不幸的是未在輸出中顯示。

我還要提及的是,我也能夠使用C_CreateObject()函數。 這將在智能卡上生成第二個ASCII文件。 但是,第二個文件我也無法用我的代碼讀出。

最可能的原因:

  • 您的ulCount變量被C_FindObjects()覆蓋為1
  • 您需要在調用C_GetAttributeValue之前將其重新分配為4
  • 這樣,您的代碼僅讀取模板中的第一個屬性。

其他一些(隨機)注意事項:

  • 由於不調用C_Login() ,因此只能查看/訪問公共對象(設置為CKA_PRIVATE的對象對您而言是隱藏的)。
  • C_FindObjectsInit() ulCount參數為零會導致您的代碼枚舉所有令牌對象-您可能希望CKA_CLASSCKA_LABEL過濾器有效。
  • 我建議不要對C_FindObjectsInit()C_GetAttributeValue()使用相同的模板
  • 您的dataValue緩沖區很小-您確定該值合適嗎?

祝好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM