openssl中的pkcs11 engine的ENGINE_by_id 怎么写
时间: 2024-03-17 11:39:40 浏览: 272
在 OpenSSL 中,pkcs11 engine 的 ID 为 "pkcs11",可以使用 ENGINE_by_id 函数获取该引擎。获取 pkcs11 engine 的示例代码如下:
```
ENGINE *e = ENGINE_by_id("pkcs11");
if (e == NULL) {
// 引擎不存在或加载失败
// 处理错误
}
```
上述代码中,如果 ENGINE_by_id 函数返回 NULL,表示指定的引擎不存在或者加载失败。否则,e 将指向获取到的 pkcs11 engine 对象,可以通过该对象调用 pkcs11 engine 提供的函数完成相应的操作。
相关问题
利用openssl 的pkcs11 engine和softHSM, 实现将证书/home/ts/cert.pem 加载到pkcs11中。C代码实现
以下是可以实现将证书加载到 pkcs11 中的示例代码。请注意,这段代码仅供参考,具体实现可能需要根据实际情况进行修改和调整。
```
#include <stdio.h>
#include <openssl/engine.h>
#include <openssl/pkcs11.h>
int main() {
// 初始化 OpenSSL 库
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
// 获取 pkcs11 引擎
ENGINE *e = ENGINE_by_id("pkcs11");
if (e == NULL) {
printf("ERROR: Failed to get pkcs11 engine\n");
return -1;
}
// 初始化 pkcs11 引擎
if (!ENGINE_init(e)) {
printf("ERROR: Failed to initialize pkcs11 engine\n");
ENGINE_free(e);
return -1;
}
// 获取 pkcs11 引擎提供的函数
const PKCS11_FUNCTIONS *pkcs11 = ENGINE_get_pkcs11(e);
if (pkcs11 == NULL) {
printf("ERROR: Failed to get pkcs11 functions\n");
ENGINE_free(e);
return -1;
}
// 初始化 pkcs11
CK_C_GetFunctionList pGetFunctionList = pkcs11->C_GetFunctionList;
CK_FUNCTION_LIST_PTR pFunctionList;
CK_RV rv = pGetFunctionList(&pFunctionList);
if (rv != CKR_OK) {
printf("ERROR: Failed to initialize pkcs11\n");
ENGINE_free(e);
return -1;
}
// 获取默认的 pkcs11 slot
CK_SLOT_ID slotId;
rv = pkcs11->C_GetSlotList(CK_TRUE, &slotId, NULL);
if (rv != CKR_OK) {
printf("ERROR: Failed to get pkcs11 slot\n");
ENGINE_free(e);
return -1;
}
// 打开 pkcs11 token
CK_SESSION_HANDLE sessionHandle;
CK_FLAGS flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
rv = pkcs11->C_OpenSession(slotId, flags, NULL, NULL, &sessionHandle);
if (rv != CKR_OK) {
printf("ERROR: Failed to open pkcs11 session\n");
ENGINE_free(e);
return -1;
}
// 读取证书
FILE *file = fopen("/home/ts/cert.pem", "r");
if (file == NULL) {
printf("ERROR: Failed to open cert file\n");
ENGINE_free(e);
pkcs11->C_CloseSession(sessionHandle);
return -1;
}
X509 *cert = PEM_read_X509(file, NULL, NULL, NULL);
fclose(file);
if (cert == NULL) {
printf("ERROR: Failed to read cert file\n");
ENGINE_free(e);
pkcs11->C_CloseSession(sessionHandle);
return -1;
}
// 将证书加载到 pkcs11 中
CK_OBJECT_HANDLE certHandle;
CK_ULONG certLen = i2d_X509(cert, NULL);
unsigned char *certData = (unsigned char *)malloc(certLen);
i2d_X509(cert, &certData);
CK_ATTRIBUTE certAttr[] = {
{CKA_CLASS, &certType, sizeof(certType)},
{CKA_TOKEN, &trueVal, sizeof(trueVal)},
{CKA_PRIVATE, &falseVal, sizeof(falseVal)},
{CKA_LABEL, "MyCertificate", sizeof("MyCertificate")},
{CKA_VALUE, certData, certLen}
};
rv = pkcs11->C_CreateObject(sessionHandle, certAttr, 5, &certHandle);
if (rv != CKR_OK) {
printf("ERROR: Failed to load cert to pkcs11\n");
ENGINE_free(e);
pkcs11->C_CloseSession(sessionHandle);
return -1;
}
// 释放资源
ENGINE_free(e);
pkcs11->C_CloseSession(sessionHandle);
X509_free(cert);
free(certData);
return 0;
}
```
上述代码中,我们首先获取 pkcs11 引擎,并初始化该引擎。然后,我们获取 pkcs11 引擎提供的函数,并使用这些函数初始化 pkcs11。接着,我们打开 pkcs11 token,并读取要加载的证书文件。最后,我们将证书加载到 pkcs11 中,并释放相关资源。
openssl + pkcs11代码
以下是一个简单的示例代码,使用 OpenSSL 和 PKCS#11 加载和使用一张智能卡中存储的证书:
```c
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <pkcs11.h>
int main(int argc, char **argv) {
// 初始化 PKCS#11 函数
CK_FUNCTION_LIST_PTR pFunctionList;
CK_RV rv = C_GetFunctionList(&pFunctionList);
if (rv != CKR_OK) {
printf("Failed to initialize PKCS#11 library: %lu\n", rv);
return 1;
}
// 打开 PKCS#11 库
CK_SLOT_ID slotId = 0; // 要使用的智能卡插槽编号
CK_SESSION_HANDLE hSession;
rv = pFunctionList->C_OpenSession(slotId, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &hSession);
if (rv != CKR_OK) {
printf("Failed to open session: %lu\n", rv);
return 1;
}
// 登录智能卡
CK_UTF8CHAR pin[] = "123456"; // 智能卡的 PIN 码
rv = pFunctionList->C_Login(hSession, CKU_USER, pin, sizeof(pin) - 1);
if (rv != CKR_OK) {
printf("Failed to login: %lu\n", rv);
return 1;
}
// 打开 PKCS#11 引擎
ENGINE *engine = ENGINE_by_id("pkcs11");
if (engine == NULL) {
printf("Failed to load PKCS#11 engine: %s\n", ERR_reason_error_string(ERR_get_error()));
return 1;
}
// 设置 PKCS#11 引擎
rv = ENGINE_ctrl_cmd_string(engine, "MODULE_PATH", "/usr/lib64/engines-1.1/pkcs11.so", 0);
if (rv != 1) {
printf("Failed to set module path: %lu\n", rv);
return 1;
}
rv = ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0);
if (rv != 1) {
printf("Failed to set PIN: %lu\n", rv);
return 1;
}
rv = ENGINE_init(engine);
if (rv != 1) {
printf("Failed to initialize engine: %lu\n", rv);
return 1;
}
// 设置默认引擎
ENGINE_set_default(engine, ENGINE_METHOD_ALL);
// 获取证书
X509 *cert = NULL;
EVP_PKEY *key = NULL;
STACK_OF(X509) *chain = NULL;
const char *certName = "mycert"; // 智能卡中存储的证书名称
rv = ENGINE_load_private_key(engine, certName, NULL, NULL, &key);
if (rv != 1) {
printf("Failed to load private key: %s\n", ERR_reason_error_string(ERR_get_error()));
return 1;
}
rv = ENGINE_load_certificate(engine, certName, &cert);
if (rv != 1) {
printf("Failed to load certificate: %s\n", ERR_reason_error_string(ERR_get_error()));
return 1;
}
chain = ENGINE_get_certificate_chain(engine, certName);
if (chain == NULL) {
printf("Failed to get certificate chain: %s\n", ERR_reason_error_string(ERR_get_error()));
return 1;
}
// 输出证书信息
printf("Certificate: %s\n", X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0));
printf("Private key: %s\n", EVP_PKEY_base_id(key) == EVP_PKEY_RSA ? "RSA" : "EC");
// 清理资源
sk_X509_pop_free(chain, X509_free);
X509_free(cert);
EVP_PKEY_free(key);
ENGINE_finish(engine);
ENGINE_free(engine);
pFunctionList->C_CloseSession(hSession);
return 0;
}
```
需要注意的是,以上代码仅供参考,具体的 PKCS#11 接口实现可能会有所不同,需要根据具体的智能卡和 PKCS#11 库进行调整。同时,该示例代码只是加载和使用证书的一部分功能,如果需要进行其他操作,需要调用相应的 PKCS#11 接口。
阅读全文