Menu

OpenSSL tpm2 provider. C++ API to issue a CSR using TPM-resident private key

2024-03-21
2024-03-22
  • Andrew Pearce

    Andrew Pearce - 2024-03-21

    Is it possible to implement the functionality shown in the bash script below from a C++ application, possibly using an OpenSSL provider obtained using:

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

    or by another method, possibly the TPM2 API directly?

    Create CSR using TPM-resident private key
    openssl req -provider tpm2 -provider default -propquery '?provider=tpm2' -new -key handle:$TPMHandle -config openssl.conf -reqexts v3_req -out device.csr

    Can the private key remain in the TPM or is it necessary to extract the private key into the application, in order to sign the CSR in the C++ code?

    I am able to create a CSR using the bash script with the openssl tpm2 provider to sign the CSR. I don't see a way to achieve the same functionality using the C or C++ APIs.

    Thank you

     
  • Andrew Pearce

    Andrew Pearce - 2024-03-21

    This code works but I retrieves the private key from the TPM. Can I achieve the same result without extracting the private key?

    EVP_PKEY * GetPrivateKeyFromTPM(void) {

    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;
    

    }

     
  • Ken Goldman

    Ken Goldman - 2024-03-21

    There is no command to get a private key from a TPM. The goal of the TPM is to protect the private key.

    The TPM has a TPM2_Sign function that will sign a digest using a key on the TPM.

     
  • Andrew Pearce

    Andrew Pearce - 2024-03-21

    I thought so too, but the OpenSSL API allows me to get the private key from the TPM and print it:

    Key Type: EC
    -----BEGIN TSS2 PRIVATE KEY-----
    M ....
    .... 8sA
    -----END TSS2 PRIVATE KEY-----

    Perhaps the attributes need to be set when I create to key to stop this. I will look at TPM2_Sign.

     
  • Andrew Pearce

    Andrew Pearce - 2024-03-22

    This code doesn't extract the private key. It give me a reference to where the key is stored so that OpenSSL can use it.

    Code explanation:
    Opening a Store Context: The OSSL_STORE_open_ex function opens a store context for a specified URI, which in this case is a TPM handle. This is a reference to where the key is stored, not the key itself. The store context is an abstraction that allows OpenSSL to access keys and other objects in a variety of locations in a uniform manner.

    Reading the Key: The code attempts to load objects from the store context using OSSL_STORE_load. For each object loaded, it checks if the object is a private key (OSSL_STORE_INFO_PKEY).

    Accessing the Private Key: If a private key is found, it is accessed via OSSL_STORE_INFO_get1_PKEY, which increases the reference count of the EVP_PKEY object, meaning the caller is responsible for freeing it. This EVP_PKEY object can then be used in OpenSSL cryptographic operations, but the actual private key material remains securely within the TPM.

    Closure and Cleanup: The loop exits once the key is found or there are no more objects to load. The store context is closed, and the EVP_PKEY object is returned for use in the application.

     
    • Ken Goldman

      Ken Goldman - 2024-03-22

      That makes sense, so GetPrivateKeyFromTPM() doesn't actually get the private key.

      Are we done, or is there more to the question?

      Note that this is a TPM project. If you have questions about the OpenSSL provider, there's surely a better forum.

       

Log in to post a comment.

MongoDB Logo MongoDB