Чтение текстового файла со смарт-карты с помощью pkcs # 11

У меня пустая смарт-карта (SLE66CX322P, Cardos 4.3b) и кард-ридер / писатель (Gemalto CT 40), Используя программное обеспечение, я могу инициализировать карту, генерировать ключи, сертификаты и т. Д. Я также могу создать простой ASCII файл с текстом, который будет храниться на смарт-карте. Как я могу прочитать содержимое этого файла ASCII в C/C++ с использованием pkcs#11 API?

Вот что я попробовал (используя также 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;

печатается четыре раза в консоли, но всегда с MyLabel а также MyData как результат, который я указал в начале CardReader::readCard(), Содержимое текстового файла на смарт-карте, конечно, отличается, но, к сожалению, не отображается в выводе.

Я также хотел бы отметить, что я также мог использовать C_CreateObject() функция. Это создало второй файл ASCII на смарт-карте. Но этот второй файл я не мог прочитать ни с моим кодом.

1

Решение

Наиболее вероятная причина:

  • Ваш ulCount переменная перезаписывается C_FindObjects() в 1,
  • Вам необходимо переназначить его 4 еще раз, прежде чем позвонить C_GetAttributeValue,
  • Таким образом, ваш код читает только первый атрибут в шаблоне.

Некоторые дополнительные (случайные) заметки:

  • Как ты не звонишь C_Login(), вы можете просматривать / получать доступ только к публичным объектам (объекты с установленным CKA_PRIVATE скрыты для вас).
  • Нуль ulCount аргумент в пользу C_FindObjectsInit() приводит к тому, что ваш код перечисляет все объекты токенов — вы, вероятно, хотели CKA_CLASS а также CKA_LABEL фильтр, чтобы быть эффективным.
  • Я бы порекомендовал не использовать тот же шаблон для C_FindObjectsInit() а также C_GetAttributeValue()
  • Ваш dataValue буфер довольно маленький — вы уверены, что значение будет соответствовать?

Удачи!

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]