从 PKCS11 读取 C++ 结构有什么问题?
What is wrong in C++ struct reading from PKCS11?
我正在尝试使用 PKCS11 库。我在 Windows10 x64 上从 C_GetInfo 函数得到了错误的结构数据。
我的代码
CK_C_GetInfo f_C_GetInfo = (CK_C_GetInfo)dlsym(__pkcs11->dlHandle, "C_GetInfo");
CK_C_Finalize f_C_Finalize = (CK_C_Finalize)dlsym(__pkcs11->dlHandle, "C_Finalize");
CK_INFO _info;
rv = f_C_GetInfo(&_info);
C++ 声明
/* an unsigned value, at least 32 bits long */
// typedef unsigned long int CK_ULONG;
typedef unsigned long int CK_ULONG;
/* at least 32 bits; each bit is a Boolean flag */
typedef CK_ULONG CK_FLAGS;
typedef struct CK_VERSION {
CK_BYTE major; /* integer portion of version number */
CK_BYTE minor; /* 1/100ths portion of version number */
} CK_VERSION;
typedef CK_VERSION CK_PTR CK_VERSION_PTR;
typedef struct CK_INFO {
CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags; /* must be zero */
CK_UTF8CHAR libraryDescription[32]; /* blank padded */
CK_VERSION libraryVersion; /* version of library */
} CK_INFO;
typedef CK_INFO CK_PTR CK_INFO_PTR;
// Function C_GetInfo
CK_RV C_GetInfo ( CK_INFO_PTR pInfo );
来自调试器的信息
错误的结构数据从参数flags
开始,它必须是0(十六进制:00 00 00 00
)。但它有十六进制值 00 00 52 75
.
如果我将参数类型 flags
更改为 char[4]
,我可以修复此错误
怎么了?为什么此结构的 PKCS11 接口错误?
前两个元素cryptokiVersion
和manufacturerID
占用34个字节。
manufacturerID
提到它的空白填充,如果你看字节,有一系列 0x20
是 UTF-8
for </code>.</p>
<p>接着是 4 <code>0x00
其次是52 75 74 ....
manufacturerID
和 flags
之间的数据中没有填充,但您的结构定义包含 2 个字节的填充以将 unsigned long
与下一个边界对齐,这将是在 36
字节处。
尝试从结构中删除填充。
#pragma pack(push, p1, 1)
typedef struct CK_INFO {
CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags; /* must be zero */
CK_UTF8CHAR libraryDescription[32]; /* blank padded */
CK_VERSION libraryVersion; /* version of library */
} CK_INFO;
#pragma pack(pop, p1)
记住这一点非常重要,根据 PKCS#11,所有结构都打包为最小大小,受平台支持,并且没有对齐到 4 或 8 字节。不这样做会使 PKCS#11 驱动程序与应用程序不兼容。 PKCS#11 标准对此很严格。
我正在尝试使用 PKCS11 库。我在 Windows10 x64 上从 C_GetInfo 函数得到了错误的结构数据。
我的代码
CK_C_GetInfo f_C_GetInfo = (CK_C_GetInfo)dlsym(__pkcs11->dlHandle, "C_GetInfo");
CK_C_Finalize f_C_Finalize = (CK_C_Finalize)dlsym(__pkcs11->dlHandle, "C_Finalize");
CK_INFO _info;
rv = f_C_GetInfo(&_info);
C++ 声明
/* an unsigned value, at least 32 bits long */
// typedef unsigned long int CK_ULONG;
typedef unsigned long int CK_ULONG;
/* at least 32 bits; each bit is a Boolean flag */
typedef CK_ULONG CK_FLAGS;
typedef struct CK_VERSION {
CK_BYTE major; /* integer portion of version number */
CK_BYTE minor; /* 1/100ths portion of version number */
} CK_VERSION;
typedef CK_VERSION CK_PTR CK_VERSION_PTR;
typedef struct CK_INFO {
CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags; /* must be zero */
CK_UTF8CHAR libraryDescription[32]; /* blank padded */
CK_VERSION libraryVersion; /* version of library */
} CK_INFO;
typedef CK_INFO CK_PTR CK_INFO_PTR;
// Function C_GetInfo
CK_RV C_GetInfo ( CK_INFO_PTR pInfo );
来自调试器的信息
错误的结构数据从参数flags
开始,它必须是0(十六进制:00 00 00 00
)。但它有十六进制值 00 00 52 75
.
如果我将参数类型 flags
更改为 char[4]
怎么了?为什么此结构的 PKCS11 接口错误?
前两个元素cryptokiVersion
和manufacturerID
占用34个字节。
manufacturerID
提到它的空白填充,如果你看字节,有一系列 0x20
是 UTF-8
for </code>.</p>
<p>接着是 4 <code>0x00
其次是52 75 74 ....
manufacturerID
和 flags
之间的数据中没有填充,但您的结构定义包含 2 个字节的填充以将 unsigned long
与下一个边界对齐,这将是在 36
字节处。
尝试从结构中删除填充。
#pragma pack(push, p1, 1)
typedef struct CK_INFO {
CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags; /* must be zero */
CK_UTF8CHAR libraryDescription[32]; /* blank padded */
CK_VERSION libraryVersion; /* version of library */
} CK_INFO;
#pragma pack(pop, p1)
记住这一点非常重要,根据 PKCS#11,所有结构都打包为最小大小,受平台支持,并且没有对齐到 4 或 8 字节。不这样做会使 PKCS#11 驱动程序与应用程序不兼容。 PKCS#11 标准对此很严格。