是否可以从 C++ 应用程序实现下面 bash 脚本中显示的功能,可能使用通过以下方式获得的 OpenSSL 提供程序:
OSSL_PROVIDER * tpm2_provider = OSSL_PROVIDER_load(NULL, "tpm2");
或者通过其他方法?
openssl req -provider tpm2 -provider default -propquery '?provider=tpm2' -新的 -钥匙句柄:$TPMHandle -config openssl.conf -reqexts v3_req -out 设备.csr
私钥是否可以保留在 TPM 中,或者是否需要将私钥提取到应用程序中,以便在 C++ 代码中签署 CSR?
我可以使用 bash 脚本和 openssl tpm2 提供程序来创建 CSR 来签署 CSR。我没有找到使用 C 或 C++ API 实现相同功能的方法。
此代码有效,但它从 TPM 检索私钥。不提取私钥也能达到同样的结果吗?
EVP_PKEY * GetPrivateKeyFromTPM(无效){
OSSL_STORE_CTX *storeCtx = NULL;
storeCtx = OSSL_STORE_open_ex("handle:0x81005020", tpm2_libctx,"?provider=tpm2", NULL, NULL, NULL,NULL, NULL);
while (!OSSL_STORE_eof(storeCtx)) {
OSSL_STORE_INFO *info = OSSL_STORE_load(storeCtx);
switch (OSSL_STORE_INFO_get_type(info)) {
case OSSL_STORE_INFO_PKEY:
EVP_PKEY *TPMpkey = OSSL_STORE_INFO_get1_PKEY(info);
if (TPMpkey) {
OSSL_STORE_close(storeCtx);
return TPMpkey;
}
break;
}
}
OSSL_STORE_close(storeCtx);
return NULL;
}
谢谢你
此 C++ 代码可用于获取对可用于加密操作的 TPM 驻留私钥的引用。密钥本身保留在 TPM 中。
就我而言,我想创建一个 CSR 并使用 TPM 驻留私钥对其进行签名。从该代码返回的 EVP_PKEY 指针可用于以正常方式使用其他 OpenSSL 库调用来签署 CSR CSR。
// TPM_Private_Key_Handle 的格式为 0x8000000
EVP_PKEY* AWSCertificateMgr::GetPrivateKeyFromTPM(const std::string & TPM_Private_Key_Handle) {
LOG4CXX_INFO(AppLogger, "Called GetPrivateKeyFromTPM");
const std::string TPMHandle = "handle:" + TPM_Private_Key_Handle;
OSSL_STORE_CTX *storeCtx = OSSL_STORE_open_ex(TPMHandle.c_str(), tpm2_libctx, "?provider=tpm2",
NULL, NULL, NULL, NULL, NULL);
if (!storeCtx) {
LOG4CXX_ERROR(AppLogger, "Failed to open store context");
return nullptr;
}
EVP_PKEY *TPMpkey = nullptr;
OSSL_STORE_INFO *info = nullptr;
while (!OSSL_STORE_eof(storeCtx) && (info = OSSL_STORE_load(storeCtx)) != nullptr) {
int type = OSSL_STORE_INFO_get_type(info);
if (type == OSSL_STORE_INFO_PKEY) {
TPMpkey = OSSL_STORE_INFO_get1_PKEY(info);
OSSL_STORE_INFO_free(info);
if (TPMpkey) {
LOG4CXX_INFO(AppLogger, "GetPrivateKeyFromTPM Succeeded");
break; // Exit the loop since the key has been found
}
} else {
OSSL_STORE_INFO_free(info); // Ensure info is freed if not the expected type
}
}
OSSL_STORE_close(storeCtx);
if (!TPMpkey) {
LOG4CXX_ERROR(AppLogger, "Failed to retrieve TPM key");
}
return TPMpkey;
}
代码说明
打开存储上下文:OSSL_STORE_open_ex 函数打开指定 URI 的存储上下文,在本例中是 TPM 句柄。这是对密钥存储位置的引用,而不是密钥本身。
存储上下文是一种抽象,允许 OpenSSL 以统一的方式访问不同位置的密钥和其他对象。
“?provider=tpm2”部分指定应使用 TPM 2.0 提供程序。
读取密钥:然后代码进入一个循环,尝试使用 OSSL_STORE_load 从存储上下文加载对象。对于加载的每个对象,它会检查该对象是否是私钥(OSSL_STORE_INFO_PKEY)。
访问私钥:如果找到私钥,则通过 OSSL_STORE_INFO_get1_PKEY 访问它,这会增加 EVP_PKEY 对象的引用计数,这意味着调用者负责释放它。
此 EVP_PKEY 对象可用于 OpenSSL 加密操作,但实际私钥材料安全地保留在 TPM 中。
关闭和清理:一旦找到键或没有更多对象要加载,循环就会退出。存储上下文关闭,并返回 EVP_PKEY 对象以供应用程序使用。