OpenSSL tpm2 提供商。使用 TPM 驻留私钥发出 CSR 的 C++ API

问题描述 投票:0回答:1

是否可以从 C++ 应用程序实现下面 bash 脚本中显示的功能,可能使用通过以下方式获得的 OpenSSL 提供程序:

OSSL_PROVIDER * tpm2_provider = OSSL_PROVIDER_load(NULL, "tpm2");

或者通过其他方法?

使用 TPM 驻留私钥创建 CSR

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;

}

谢谢你

openssl tpm-2.0
1个回答
0
投票

此 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 对象以供应用程序使用。

© www.soinside.com 2019 - 2024. All rights reserved.