tpm2-software / tpm2-openssl

OpenSSL Provider for TPM2 integration
BSD 3-Clause "New" or "Revised" License
88 stars 37 forks source link

Converting TSS2 PRIVATE KEY to RSA private Key for parsing the key into EVP_PKEY structure failed #91

Closed sumanth797 closed 10 months ago

sumanth797 commented 1 year ago

Hi,

I have loaded the Private Key from TPM using openssl command,

openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -out privatekey.pem -in handle:0x81010002

And the content of Private key is, -----BEGIN TSS2 PRIVATE KEY----- MIIBNQYGZ4EFCgEDoAMBAQECBEAAAAEEggEYARYAAQALAAYAcgAAABAAEAgAAAAA AAEA1ulSPzuYEDTez5D8VOczFDVMRliHQ748NB9KYSlKn0H7QPO3gpHOrzR6tNS8 mNki3MtoizWb8LU9fq5J98rLJzC1kzisF4tjYXqs+QcK7MU1HfeGxa+dwtY8d6jI Z2uew5i3u3nVPl/07tCwPXdv9FRjl5JoNPpADu7zmVMggwAEN6E+xw6PfouMWCwS 7R3p5IZFRZQn+lrX8xPPbcB7ImxfPjqx16PhknSng7PyQNMBkJNO0pA+20SxP4aP WkG0SwbLJM+9QJQ6x9dpyTIK0pl4XJyryuE7yvv/qxZqeL6eThLFhaOlfwYROdsH E2dsWX1sLdgNwVEy3sno6aR+CQQEAAIBgQ== -----END TSS2 PRIVATE KEY-----

But i want to convert to RSA based private key -----BEGIN PRIVATE KEY----- MIIBNQYGZ4EFCgEDoAMBAQECBEAAAAEEggEYARYAAQALAAYAcgAAABAAEAgAAAAA ............................

Is there any API to do the conversion for parsing the key into EVP_PKEY structure

gotthardp commented 1 year ago

1) The private key never leaves the TPM chip, so you never get the BEGIN PRIVATE KEY. It will always be the BEGIN TSS2 PRIVATE KEY, however: 2) Using the tpm2 provider the BEGIN TSS2 PRIVATE KEY can be loaded into the EVP_PKEY structure and used in all situations (with some restrictions) like any other private key. Have a look at https://github.com/tpm2-software/tpm2-openssl/blob/master/test/rsa_genpkey_decrypt.c

sumanth797 commented 1 year ago

Hi , I have used the above example for loading into EVP_PKEY structure. https://github.com/tpm2-software/tpm2-openssl/blob/master/test/rsa_genpkey_decrypt.c

I'm loading the provider from this path if ((defprov = OSSL_PROVIDER_load(NULL, "/usr/lib64/ossl-packages/tpm2.so")) == NULL) goto error;

It is throwing this error, PROVIDER INIT RSA GEN INIT rsa 3 RSA GEN_SET_PARAMS [ bits ] RSA GEN 2048 bits RSA GEN parent: primary 0x40000001 WARNING:esys:src/tss2-esys/api/Esys_CreatePrimary.c:400:Esys_CreatePrimary_Finish() Received TPM Error ERROR:esys:src/tss2-esys/api/Esys_CreatePrimary.c:135:Esys_CreatePrimary() Esys Finish ErrorCode (0x000009a2) RSA FREE RSA CLEANUP 80CB564DE77F0000:error:40000002:/usr/lib64/ossl-packages/tpm2.so:tpm2_build_primary:authorization failure:src/tpm2-provider-pkey.c:316: PROVIDER TEARDOWN Can you help me how to pass the password and rectify this issue?

gotthardp commented 1 year ago

You need to set the parent-auth parameter as described in https://github.com/tpm2-software/tpm2-openssl/blob/master/docs/keys.md#key-generation

To set that you need something like

    OSSL_PARAM params[3];
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", "provider=tpm2");

        params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits);
    params[1] = OSSL_PARAM_construct_utf8_string("parent-auth", "password", 0);
    params[2] = OSSL_PARAM_construct_end();

    if (EVP_PKEY_keygen_init(pctx) && EVP_PKEY_CTX_set_params(pctx, params))
        EVP_PKEY_generate(pctx, &pkey);
sumanth797 commented 1 year ago

Hi, I'm trying to load the key from the specific handler (handle:0x81010002), I'm not generating new RSA Private key. Is there any APIs to load the key from the handler and convert to EVP_PKEY structure.

For Ex, Load the Private Key, openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -out privatekey.pem -in handle:0x81010002?pass -passin pass:ynM67sdZjEJesWk6

Convert the privatekey.pem to EVP_PKEY Structure And the content of Private key is, -----BEGIN TSS2 PRIVATE KEY----- MIIBNQYGZ4EFCgEDoAMBAQECBEAAAAEEggEYARYAAQALAAYAcgAAABAAEAgAAAAA AAEA1ulSPzuYEDTez5D8VOczFDVMRliHQ748NB9KYSlKn0H7QPO3gpHOrzR6tNS8 mNki3MtoizWb8LU9fq5J98rLJzC1kzisF4tjYXqs+QcK7MU1HfeGxa+dwtY8d6jI Z2uew5i3u3nVPl/07tCwPXdv9FRjl5JoNPpADu7zmVMggwAEN6E+xw6PfouMWCwS 7R3p5IZFRZQn+lrX8xPPbcB7ImxfPjqx16PhknSng7PyQNMBkJNO0pA+20SxP4aP WkG0SwbLJM+9QJQ6x9dpyTIK0pl4XJyryuE7yvv/qxZqeL6eThLFhaOlfwYROdsH E2dsWX1sLdgNwVEy3sno6aR+CQQEAAIBgQ== -----END TSS2 PRIVATE KEY-----

Can you help us here?

gotthardp commented 1 year ago

Well, without password it looks like this:

    OSSL_STORE_CTX *ctx;

    if (ctx = OSSL_STORE_open("handle:0x81010002", NULL, NULL, NULL, NULL)) {
        while (OSSL_STORE_eof(ctx) == 0) {
            OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
            if (info && OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
                EVP_PKEY *pkey = OSSL_STORE_INFO_get0_PKEY(info);

                OSSL_STORE_INFO_free(info);
            }
        }
    }
sumanth797 commented 1 year ago

It requires password also

gotthardp commented 1 year ago

I added a new example that demonstrates the use of OSSL_STORE_open with a password: https://github.com/tpm2-software/tpm2-openssl/blob/master/test/ec_genpkey_store_load.c

sumanth797 commented 1 year ago

Hi, This is the overall Code for loading the TPM2TSS Private key in EVP_PKEY Structure.

code:

include <openssl/provider.h>

include <openssl/evp.h>

include <openssl/rsa.h>

include <openssl/err.h>

include <openssl/store.h>

include

int main() { const char password = "Aw2WLz9bHAideywh"; OSSL_PROVIDER defprov = NULL; OSSL_STORE_CTX ctx = NULL; OSSL_STORE_INFO info = NULL; UI_METHOD ui_method = NULL; std::string tpm_key_path = "handle:0x81010002"; std::string vendor_key_password = "ynM67sdZjEJesWk6"; OSSL_PARAM params[3]; EVP_PKEY pkey = NULL; BIO out = BIO_new_fp( stdout, BIO_NOCLOSE ); if ( ( defprov = OSSL_PROVIDER_load( NULL, "/usr/lib64/ossl-packages/tpm2.so" ) ) ) { if ( ( ctx = OSSL_STORE_open( tpm_key_path.c_str(), nullptr, (void )password, nullptr, nullptr ) ) ) { while ( !OSSL_STORE_eof( ctx ) ) { OSSL_STORE_INFO *info = OSSL_STORE_load( ctx ); if ( ( info && OSSL_STORE_INFO_get_type( info ) == OSSL_STORE_INFO_PKEY ) ) { pkey = OSSL_STORE_INFO_get0_PKEY( info ); EVP_PKEY_print_private(out, pkey, 0, NULL); BIO_free(out); std::cout <<"true\n"; OSSL_STORE_INFO_free( info ); } } } } if ( pkey ) { std::cout << "not empty\n"; } ERR_print_errors_fp(stderr); OSSL_STORE_close(ctx); OSSL_PROVIDER_unload(defprov); return 0; }

This is the output generated: PROVIDER INIT STORE/OBJECT OPEN handle:0x81010002 STORE/OBJECT LOAD STORE/OBJECT LOAD pkey STORE/OBJECT LOAD found RSA RSA LOAD RSA GET_PARAMS [ bits security-bits max-size ] RSA HAS 1 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x87 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x87 ENCODER rsa pkcs1/der DOES_SELECTION 0x87 ENCODER rsa pkcs1/der DOES_SELECTION 0x87 ENCODER rsa pkcs1/der DOES_SELECTION 0x87 ENCODER rsa pkcs1/der DOES_SELECTION 0x87 ENCODER rsa pkcs1/pem DOES_SELECTION 0x87 ENCODER rsa pkcs1/pem DOES_SELECTION 0x87 ENCODER rsa pkcs1/pem DOES_SELECTION 0x87 ENCODER rsa pkcs1/pem DOES_SELECTION 0x87 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x87 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x87 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x87 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x87 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x87 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x87 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x87 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x87 ENCODER ENCODE rsa text Private-Key: (RSA 2048 bit, TPM 2.0) Modulus: 00:c2:51:73:e2:b3:a8:34:9c:5d:13:de:6b:19:69: 88:3c:ef:d1:74:86:6c:43:a5:72:87:b9:e3:d6:60: 82:84:e8:24:f9:78:d1:8f:f8:e5:a2:82:d9:aa:f4: 18:b7:fa:83:5b:88:a7:d8:ab:82:d9:b7:52:b0:e1: 4d:c7:c7:1e:fb:4a:3a:6e:0a:8f:c6:31:d8:4a:12: 8e:a0:0b:b4:ea:62:62:70:10:12:80:60:c4:17:0b: de:30:68:b5:76:34:aa:52:8a:79:e8:88:38:82:53: 60:a2:63:b4:23:bb:13:c0:c0:cc:a6:72:c3:3e:74: 9e:e3:e1:22:b6:20:96:de:30:ca:e5:4e:8a:ad:83: 3a:a3:fc:81:a9:c0:26:79:ea:76:15:06:15:4d:7a: 5c:00:d5:25:c4:89:d7:c4:80:96:dd:8c:33:c9:62: 80:82:0a:0b:ef:a8:d5:97:74:4e:d6:b6:39:d1:08: 32:dc:1b:1c:d6:66:99:b3:f1:73:14:75:a4:b4:04: 2e:36:3f:14:bb:15:37:ab:84:17:cc:84:2e:90:bf: b2:bb:5e:75:4b:71:e5:ef:79:6b:8a:df:36:85:a4: 33:51:a1:41:03:3e:3f:4a:3f:22:a8:91:b2:e3:61: aa:db:da:e4:19:ba:59:0c:b0:a3:4c:10:31:85:16: 6d:e7 Exponent: 65537 (0x10001) Object Attributes: fixedTPM fixedParent sensitiveDataOrigin userWithAuth decrypt sign / encrypt Signature Scheme: Hash: true RSA FREE not empty STORE/OBJECT CLOSE PROVIDER TEARDOWN

so, Is this pkey is of EVP_PKEY format? And also i want to confirm whether pkey generated can be stored in pem file which will be later used to parse the file using PEM_read_PrivateKey in EVP_PKEY format? Let us know if i'm on the right track.

gotthardp commented 1 year ago

Yes, it's the EVP_PKEY structure. The TPM-based private key can be stored in a PEM file, which can be later loaded using OSSL_STORE_load. The PEM_read_PrivateKey doesn't work for TPM handles, but the OSSL_STORE_load loads the PEM into the EVP_PKEY structure.

sumanth797 commented 1 year ago

**Can you share the full code using OSSL_STORE_load?**

gotthardp commented 1 year ago

I already did: https://github.com/tpm2-software/tpm2-openssl/blob/master/test/ec_genpkey_store_load.c

sumanth797 commented 1 year ago

Sorry, I didn't check it properly. Thanks for your support!

sumanth797 commented 1 year ago

I'm trying to free pkey data using EVP_PKEY_free(pkey); but it got hung and the process is not finished. I had to abort the process manually. Can you let me know how to free it?

gotthardp commented 1 year ago

As you said: EVP_PKEY_free(pkey) is the right function.

sumanth797 commented 1 year ago

But it is not freeing up , and there is no PROVIDER TEARDOWN and got hung It is getting hung, RSA FREE STORE/OBJECT CLOSE

without using EVP_PKEY_free(pkey); It is getting exited successfully RSA FREE STORE/OBJECT CLOSE not empty PROVIDER TEARDOWN

code: EVP_PKEY tpmPrivateKeyEvpPkeyFormat( ) { std::string vendorKeyPassword; OSSL_PROVIDER defprov = NULL; OSSL_STORE_CTX ctx = NULL; OSSL_STORE_INFO info = NULL; std::string tpm_key_path = std::string( "handle:" ) + TPM_PERSISTENT_HANDLE; EVP_PKEY pkey = NULL; if ( checkPersistentValue( TPM_PERSISTENT_HANDLE ) ) { if ( fetchVendorPassowrd( vendorKeyPassword ) ) { std::cout << "vendorKeyPassword is " << vendorKeyPassword << "\n"; BIO out = BIO_new_fp( stdout, BIO_NOCLOSE ); if ( ( defprov = OSSL_PROVIDER_load( NULL, "/usr/lib64/ossl-packages/tpm2.so" ) ) ) { if ( ( ctx = OSSL_STORE_open( tpm_key_path.c_str(), nullptr, (void )vendorKeyPassword.c_str(), nullptr, nullptr ) ) ) { while ( !OSSL_STORE_eof( ctx ) ) { OSSL_STORE_INFO info = OSSL_STORE_load( ctx ); if ( ( info && OSSL_STORE_INFO_get_type( info ) == OSSL_STORE_INFO_PKEY ) ) { pkey = OSSL_STORE_INFO_get0_PKEY( info ); // EVP_PKEY_print_public( out, pkey, 0, NULL ); // std::cout << "=======================\n"; EVP_PKEY_print_private( out, pkey, 0, NULL ); BIO_free( out ); std::cout <<"true\n"; OSSL_STORE_INFO_free( info ); } } } } ERR_print_errors_fp( stderr ); OSSL_STORE_close( ctx ); OSSL_PROVIDER_unload( defprov ); } } return pkey; }

and in main() EVP_PKEY *pkey = tpmPrivateKeyEvpPkeyFormat( ); if ( pkey ) { std::cout << "not empty\n"; } EVP_PKEY_free(pkey); return 0;

Let me know if i'm making mistake, eventually it should free it, but it's not happening?

gotthardp commented 1 year ago

Then OSSL_PROVIDER_load and unload must be in main the first and the last command. You must not free the provider before freeing the key handled by that provider.

sumanth797 commented 1 year ago

It is still the same, Can you help me by correcting the code ? EVP_PKEY tpmPrivateKeyEvpPkeyFormat( OSSL_PROVIDER defprov ) { std::string vendorKeyPassword; OSSL_STORE_CTX ctx = NULL; OSSL_STORE_INFO info = NULL; std::string tpm_key_path = std::string( "handle:" ) + TPM_PERSISTENT_HANDLE; EVP_PKEY pkey = NULL; if ( checkPersistentValue( TPM_PERSISTENT_HANDLE ) ) { if ( fetchVendorPassowrd( vendorKeyPassword ) ) { std::cout << "vendorKeyPassword is " << vendorKeyPassword << "\n"; BIO out = BIO_new_fp( stdout, BIO_NOCLOSE ); if ( defprov ) { if ( ( ctx = OSSL_STORE_open( tpm_key_path.c_str(), nullptr, (void )vendorKeyPassword.c_str(), nullptr, nullptr ) ) ) { while ( !OSSL_STORE_eof( ctx ) ) { OSSL_STORE_INFO info = OSSL_STORE_load( ctx ); if ( ( info && OSSL_STORE_INFO_get_type( info ) == OSSL_STORE_INFO_PKEY ) ) { pkey = OSSL_STORE_INFO_get0_PKEY( info ); // EVP_PKEY_print_public( out, pkey, 0, NULL ); // std::cout << "=======================\n"; EVP_PKEY_print_private( out, pkey, 0, NULL ); BIO_free( out ); std::cout <<"true\n"; OSSL_STORE_INFO_free( info ); } } } } ERR_print_errors_fp( stderr ); OSSL_STORE_close( ctx ); } } return pkey; }

int main() { OSSL_PROVIDER defprov = NULL; defprov = OSSL_PROVIDER_load( NULL, "/usr/lib64/ossl-packages/tpm2.so" ); EVP_PKEY pkey = tpmPrivateKeyEvpPkeyFormat( defprov ); if ( pkey ) { std::cout << "not empty\n"; } if ( defprov) { std::cout << " not defprov\n"; } EVP_PKEY_free(pkey); if ( !pkey ) { std::cout << "empty\n"; } OSSL_PROVIDER_unload( defprov ); // return 0; }

gotthardp commented 1 year ago

Try OSSL_STORE_INFO_get1_PKEY instead OSSL_STORE_INFO_get0_PKEY. You should read the man pages to understand the difference.

sumanth797 commented 1 year ago

I'm a newbie to this, I'm not able to understand it. So I'm requesting for your help

gotthardp commented 1 year ago

I can help, but as a newbie you should learn and try to understand what you are doing, otherwise you will never improve. :-)

sumanth797 commented 1 year ago

I tried it, but still it was holding something and it was not NULL

gotthardp commented 1 year ago

The pkey will not be NULL after calling EVP_PKEY_free(pkey);

sumanth797 commented 1 year ago

I really appreciate your help, Thank You So much.

sumanth797 commented 1 year ago

Hi, Do we have cmp support for tpm2 tss key format. I'm trying to set a private key (EVP_PKEY) which is of TSS2 PRIVATE KEY format. in the context of a CMP operation., by using OSSL_CMP_CTX_set1_pkey(cmpCtx, privatekey) api . But it is not able to do it. We are getting the following error when we use the TSS2 EVP_PKEY for CMP IR request -

00B7AA37EF7F0000:error:068000DE:asn1 encoding routines:asn1_template_ex_i2d:illegal zero content:crypto/asn1/tasn_enc.c:374: 00B7AA37EF7F0000:error:0488000D:PEM routines:PEM_ASN1_write_bio:ASN1 lib:crypto/pem/pem_lib.c:341: 00B7AA37EF7F0000:error:020000B3:rsa routines:rsa_ossl_private_encrypt:missing private key:crypto/rsa/rsa_ossl.c:332: 00B7AA37EF7F0000:error:1C880004:Provider routines:rsa_sign:RSA lib:providers/implementations/signature/rsa_sig.c:588: 00B7AA37EF7F0000:error:06880006:asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:crypto/asn1/a_sign.c:284: 00B7AA37EF7F0000:error:1D00007F:CMP routines:ossl_cmp_msg_protect:error protecting message:crypto/cmp/cmp_protect.c:332: 00B7AA37EF7F0000:error:1D0000A3:CMP routines:ossl_cmp_certreq_new:error creating certreq:crypto/cmp/cmp_msg.c:439:

So is there any API which supports this format TSS2 PRIVATE KEY?

gotthardp commented 1 year ago

This test demonstrates that CMP is supported to a certain extent: https://github.com/tpm2-software/tpm2-openssl/blob/master/test/rsa_genpkey_x509_cmp.sh

Please create a short script or .c file that I can build and execute to reproduce the error you are getting.

sumanth797 commented 1 year ago

Hi, Sorry for the above mis info, Creating CMP ctx, OSSL_CMP_CTX *cmp_ctx=NULL; cmp_ctx = OSSL_CMP_CTX_new(NULL, NULL);

These are the errors we are facing while sending the IR request, 00B7AA37EF7F0000:error:068000DE:asn1 encoding routines:asn1_template_ex_i2d:illegal zero content:crypto/asn1/tasn_enc.c:374: 00B7AA37EF7F0000:error:0488000D:PEM routines:PEM_ASN1_write_bio:ASN1 lib:crypto/pem/pem_lib.c:341: 00B7AA37EF7F0000:error:020000B3:rsa routines:rsa_ossl_private_encrypt:missing private key:crypto/rsa/rsa_ossl.c:332: 00B7AA37EF7F0000:error:1C880004:Provider routines:rsa_sign:RSA lib:providers/implementations/signature/rsa_sig.c:588: 00B7AA37EF7F0000:error:06880006:asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:crypto/asn1/a_sign.c:284: 00B7AA37EF7F0000:error:1D00007F:CMP routines:ossl_cmp_msg_protect:error protecting message:crypto/cmp/cmp_protect.c:332: 00B7AA37EF7F0000:error:1D0000A3:CMP routines:ossl_cmp_certreq_new:error creating certreq:crypto/cmp/cmp_msg.c:439:

With pre-shared keys and reference number the same solution is working. On replacing the pre-shared key and reference number with vendor certificates we are seeing the errors Let us know, are we making any mistake here?

gotthardp commented 1 year ago

Please try to reproduce the issue with a small .c file that you can share with me and I can then build and run.

sumanth797 commented 12 months ago

Hi, I'm Sharing the code in c++ , file name is opensource_tpm.cpp To create the executable file, run
g++ opensource_tpm.cpp -o opensource_tpm -lssl -lcrypto and run ./opensource_tpm binary for performing IR request using cmp api's

This is the code: opensource_tpm.txt Save the above file as opensource_tpm.cpp

CodeLink: https://github.com/tpm2-software/tpm2-openssl/files/13224218/opensource_tpm.txt

serialNo.txt rsa_private_key.txt

Pem Files Link: https://github.com/tpm2-software/tpm2-openssl/files/13224256/serialNo.txt https://github.com/tpm2-software/tpm2-openssl/files/13224257/rsa_private_key.txt

Save the serialNo.txt as serialNo.pem, rsa_private_key.txt as rsa_private_key.pem and change the path in the code after placing the pem files in appropriate location and execute the code for sending IR Request using CMP Protocol

Performed TPM Steps Link: [TPM_CSR_GENERATION.txt] https://github.com/tpm2-software/tpm2-openssl/files/13224422/TPM_CSR_GENERATION.txt This below TPM_CSR_GENERATION file will give info on how we are generating the private key and also the CSR file by persisting the handle. Let us know, are we making any mistake here.

This is the output: It is failing with tpm private key only

./opensource_tpm

-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCS5IpPJtvBar9I 02OohNtjWxu/ySob7fPmjALtOLCxpjEr0b4GMfcwyL+/a7+hRvs583grBXOIgcQK KzsXp1GQ5V1+Nfz0YveucWKI0+lQK/u7NbIgYGQ422QorfJv9XIUMhN1Zp0+h/2l cmp2x+nY2fQ1U8x/Tl2DdqSNSlng9zAkXqozEdbPpFi7tuWk6gidVxYbyrWQPkI3 wj/uHBKGe9QB8Vmc7zRgQ4TGkYO46l31r8Q+ITKJZZU3FNwHJj+PXTOhAivaI1yF GheyX6MzrCNRxw0mmPZRZjYZiU/wxNwekkp+BfBoRVhaBO9kftfJhgSHfSoCmU6A Edk1+VLDAgMBAAECggEABBjLV2V3jT+bbH4M0lc7loak0aaxfcxCAwTrqKRt9Ske nPYWwoMj6Es+YdSGUzVbbg8sI6hdbl9kJtPJgaGL2lUzVCulovFHBClVvLLgV86U 5kXwnQuN2rIaazIIHXbvLWtaHz+d6hpj3iNAnzsjJVuq086YWQKdWWchNBmbQ8rG Tm7Obl/jEHYx7MhyXbgj/FpA0PB3zEI9+s2Sw9DyYpbVpW8fJy2kplfjQXxCPXpn 5xsANKy/+tSm6/Qs0Qx7yM1QTav+/35irOns6alK5vlEOjFtXsa4Xq+e0ATdkeww 5iYVs8eQ+sms82LKOH+q49reeo/1r4Qs1ghhl/TeVQKBgQDETjdiPMuoCtIKw83/ nmt/XQYy6M0Fr3mabx6W0MI/olH8ZEDmSu0+v3S0feWtOYCNJB90ItSd+Qi/6Lck C26c+aacvwUfAvGv7YXp2uzrRnurbrIJBI5T3BI0aLXAxzizMNJNE52dr5igcmZF PLpGOWt9Er7mUJbp650ks9k0nwKBgQC/j7BwV81kenY7t6pFuxKp9JT6X/q2bcys 3bvVjSgHYlLYiRA8qAHv107VsZ5EepuNbS4W9lqQd7exz3AfIHyf6DdVUKNL+/Os 7HZZFWT17yxU8tcUNgKhg69wvG0YbI0kVEwFRx9RP3UVIIra5rosXnDNzB+vitAi Hgfu+zWrXQKBgEW7QxEyZ2WZ8mLAizxyGd10Pe93otySKLAjKMqJ/XZ9QoJVWnhz xTK078/tqNiPxIpeeo3WkZBMFj+Vevji1rgMNpMXh8osUY4c4aTgj6hDsUqEV9m8 NJK1agIT7/w6yHlerlWS0jphVeYovQt7NvAbFYOoVQebOQB/IaMX/+AhAoGBALc1 3jIUR8TJuzryNk/q07bozXOJSGgiK5dJmtRr5NTrHQEsVfMtXGzfJ+8Jqa0k9pEU 0vfzNjrlxTKyizG6CHeHySQ3s3aAylWg8q/Q3na5AVVdzIbwASQopirUjCLH71XH qc2CcFlsr7Y9IZCrC3RT/t9VUxi5UsbOohfW+0WhAoGAWEdjkznjlGvhfLWf5oc8 dM7GAJQZfdcOoS/tXNy6xFtEc9cxOTGL6x9NQug8JE7SdTQCuOuC1jD+qYZobYxL RdBVitxddgVt5hSCmscd2jVPbI9shOGUlxnfTZOcHIdYYxkoOV+S8YJ3ZbKV5jj0 Og/i0snZlTz7pto/khEDvxo= -----END PRIVATE KEY-----

PROVIDER INIT vendorKeyPassword is Aw2WLz9bHAideywh STORE/OBJECT OPEN handle:0x81010002?pass STORE/OBJECT LOAD tpm_password_callback is Aw2WLz9bHAideywh size is 64 STORE/OBJECT LOAD pkey STORE/OBJECT LOAD found RSA RSA LOAD RSA GET_PARAMS [ bits security-bits max-size ] RSA HAS 1 fetched pkey STORE/OBJECT CLOSE -----BEGIN CERTIFICATE----- MIIEvzCCAqegAwIBAgIFARJ0fjMwDQYJKoZIhvcNAQELBQAwOjEOMAwGA1UECgwFTm9raWExKDAm BgNVBAMMH0ZhY3RvcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMjMxMDMxMTAyNDI2WhcN NDExMDI2MTA1NDI2WjBdMSUwIwYDVQQKDBxOb2tpYSBTb2x1dGlvbnMgYW5kIE5ldHdvcmtzMTQw MgYDVQQDDCtRVEZDV04yMjQwMDY2Lm5va2lhc29sdXRpb25zYW5kbmV0d29ya3MuY29tMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtQ6/Up8Vkq/hGXV7yUWvyrw9ZPXRrWvYVCMz30mr AZV7ofcSBqktQ2vtroNPBliMa2Vvi6tgR8KpWJIfLUIG3c8dZpXq0G7fsg75CkEsaqeXDJtXVtIt bO59CVbW3ZTR3vDhRRinbYLDgjbMWaOetGirPVcClbI8BNg1WI89f8Ig0VjQPPrxAsfbEIazDro1 FYsXTnEnp3ztp+kZkqg2L6V5Rf2REWQvc3IyKHktABuCJHGeq9qEWWmGTkCLzRLguSAmGHxWOAEW 6cPSdebaiDsWe5UL342tMgPvRVmocj3EGav1hwnkq0HIpLuO1KKnjyB8hSo+FVI2bfEomCFsiwID AQABo4GoMIGlMB8GA1UdIwQYMBaAFMwqtHm2sKHPYIy+6B9zT8Xz9BHPMB0GA1UdDgQWBBTOSqKk +cs2N8YvsfYk+NsbWQQ5YzAOBgNVHQ8BAf8EBAMCBaAwGwYDVR0gBBQwEjAQBg4rBgEEAYHeKgEP AQICATA2BgNVHREELzAtgitRVEZDV04yMjQwMDY2Lm5va2lhc29sdXRpb25zYW5kbmV0d29ya3Mu Y29tMA0GCSqGSIb3DQEBCwUAA4ICAQAV3sHaLsIAANn3odNoJW9WaN8U9K8vvQafi7/P5G4p7JSo Mg5j9P8DN3V+8SmVnGlHPHhSFM+bQffvQYbQtcqbFDZAVAuGV9sLZ9rnPrsm0vziHKbzPz8ZW74P T2WXHoIPwzDdweRe1ELKzjQV1f31Eoe+fnrQIUK/YWCzAOQyqKmB+KGnhQMhJjZDpplmir3/Dcf+ cAbMu4eZtV+aIGTvgkDqwVFkm/JMsb63GKdRPywHHjARujixL8jRxta2cMxAQOZaUBiUEd4/Yui8 Tqpm51oI9mUH+g6pCQU21zq52q6bhJjJIgOkmL81UnK+nk65nUHHoxTun9ySyZSLH52aMlUE9rl5 28untgtqjSwhXIBM4Qm62acQMas8FF1rVSK/QKa5dPsmlc+mzN0sBODFUL6p92zbt0TNLNXU9utH 0vDCnEj1rxEz2WFQcB7riXyjNcNf+Z9b+oyAebIGaq4Qykl7rB4M1hhwXT7jWQcSWV0a4voJmoGf 16oXaeNP5pbGUQOK+5RKW3X2Xhesk9LlvhFgnBtHX9OU+NzFbbPyZdmjcjLHpmRgsFlNfJ5Ih8AG X/2juXwjea4DitQAJvixgxb8Xsru4MbnsC0PrkkRitBBu+sX0UY0enC89FvgXK8VoLIWoT8HqnCU 9gff38Az0i3ltXFZ/FKqgohu1PJIeA== -----END CERTIFICATE-----

DIGEST SHA1 GET_PARAMS [ blocksize size xof algid-absent ] DIGEST SHA256 GET_PARAMS [ blocksize size xof algid-absent ] DIGEST SHA384 GET_PARAMS [ blocksize size xof algid-absent ] ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der ENCODE 0x86 RSA GET_PARAMS [ default-digest mandatory-digest ] RSA EXPORT 87 IR is failed failed code is -1 failed cmp ctx CMP error: missing private key CMP error: RSA lib CMP error: EVP lib CMP error: error creating certreq RSA FREE

gotthardp commented 11 months ago

Hmm, there are bugs in the key generation guideline and the .cpp file:

One this is fixed the CMP feels correct, but it fails for me because the peer server is not accessible.

sumanth797 commented 11 months ago

I couldn't understand what you mean by generate a certificate. can you elaborate more on this, and also can you share any example? And also for the password, the guide is just an reference on how i generated in another machine, and the password in the .cpp file it is different. can you tell me what password I have to pass from the guide I shared?

gotthardp commented 11 months ago

It's ynM67sdZjEJesWk6 that should be used as a password, not Aw2WLz9bHAideywh. Also, there are no steps how to generate the serialNo.pem file, which is required and must match the TPM key, so I couldn't use the one you supplied.

sumanth797 commented 11 months ago

Hi, This is how I generated the key pair and persisted it with the correct password. echo Jz7AATQApZAx3OdGrikOqohgI6Ux5MGktKbhiExFJdbvLFE9dlPLuaRmA4VYg8fLcBhFDQaAcmpxZvguAqbwCM3ZZVhN1iSlhAZD75SYuo4o8n9tm5cm44OAnLB7M5m2QQkdZZqsMQ6FpPOAHBFoEwI2Y1PFAB0dponCuAUIfPSlZXgmKILvJvc54HQALadted4C9gbrYS6ZyjfU9GNNckaoegqVWnFSvoCDEcaRTeExkKeHBZNfkIP79VPZYSh |tpm2 createprimary -C e -G rsa2048 -a 'restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth' -u - -c /working_dir/endorsementkey.ctx -P GosKS1xXvgkM6bSm -p qx2lAO8Jf4RbXJBb

tpm2_evictcontrol -C o -c /working_dir/endorsementkey.ctx 0x81010001 -P vMHuwlrSsGXNSXER

tpm2_create -C 0x81010001 -a 'fixedtpm|fixedparent|sensitivedataorigin|userwithauth|decrypt|sign' -u /working_dir/vendorkey.pub -r /working_dir/vendorkey.priv -P qx2lAO8Jf4RbXJBb -p Aw2WLz9bHAideywh

tpm2_load -C 0x81010001 -u /working_dir/vendorkey.pub -r /working_dir/vendorkey.priv -c /working_dir/vendorkey.ctx -P qx2lAO8Jf4RbXJBb

tpm2_evictcontrol -C o -c /working_dir/vendorkey.ctx 0x81010002 -P vMHuwlrSsGXNSXER

And CSR File is generated using,

openssl req -new -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -key handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh -out /working_dir/vendorkey.csr -config /config/csr.cnf

And tpm_private_key is generated using,

openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -out tpm_privatekey.pem -in handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh

And tpm_public_key is generated using,

openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -pubout -out tpm_publickey.pem -in handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh

And serialNo.pem is generated using,

We have serialNo.pem generated by using the vendorkey.csr from above and then CSR File is sent to the ca server to get it. And CA Server directly we cannot access it directly.

And rsa_private_key.pem,

openssl genrsa -out rsa-private.pem 2048

Attached the keys and pem files generated in the below link,

TPM_PEM_FILES.zip Link for files: https://github.com/tpm2-software/tpm2-openssl/files/13295681/TPM_PEM_FILES.zip

Prerequisite for sending IR using cmp:

sumanth797 commented 11 months ago

I tried the same using the cmp command and IR is being Sent, but failed to send IR using the above c++ code. Command: openssl cmp -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -provider default -propquery '?provider=tpm2,tpm2.digest!=yes' -cmd ir -server 10.33.123.231:8081/pkix/ -recipient "/CN=CMPserver" -cert /working_dir/serialNo.pem -key handle:0x81010002?pass -keypass pass:Aw2WLz9bHAideywh -subject "/CN=Client" -certout test-my-cert.pem -cacertsout test-my-ca.pem console: cmp_main:apps/cmp.c:2833:CMP info: using section(s) 'cmp' of OpenSSL configuration file '/etc/pki/tls/openssl.cnf' cmp_main:apps/cmp.c:2842:CMP info: no [cmp] section found in config file '/etc/pki/tls/openssl.cnf'; will thus use just [default] and unnamed section if present PROVIDER INIT DIGEST SHA1 GET_PARAMS [ blocksize size xof algid-absent ] DIGEST SHA256 GET_PARAMS [ blocksize size xof algid-absent ] DIGEST SHA384 GET_PARAMS [ blocksize size xof algid-absent ] STORE/OBJECT OPEN handle:0x81010002?pass STORE/OBJECT SET_PARAMS [ properties ] STORE/OBJECT SET_PARAMS [ expect ] STORE/OBJECT LOAD STORE/OBJECT LOAD pkey STORE/OBJECT LOAD found RSA RSA LOAD RSA GET_PARAMS [ bits security-bits max-size ] RSA HAS 1 STORE/OBJECT CLOSE setup_protection_ctx:apps/cmp.c:1448:CMP warning: will not authenticate server due to missing -secret, -trusted, or -srvcert DER DECODER DECODE setup_client_ctx:apps/cmp.c:2009:CMP info: will contact http://10.33.123.231:8081/pkix/ RAND NEW RAND NEW RAND GET_CTX_PARAMS [ max_request ] RAND GENERATE RAND GET_CTX_PARAMS [ max_request ] RAND GENERATE ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/der DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER tss PrivateKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/der DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa pkcs1/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/der DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 ENCODER rsa SubjectPublicKeyInfo/pem DOES_SELECTION 0x86 RSA GET_PARAMS [ default-digest mandatory-digest ] SIGN DIGEST_INIT rsa MD=SHA2-256 SIGN GET_CTX_PARAMS [ algorithm-id ] SIGN DIGEST_SIGN estimate SIGN DIGEST_SIGN RSA HAS 2 RSA NEW RSA IMPORT [ n e ] RSA MATCH 0x6 SIGN DIGEST_INIT rsa MD=SHA256 SIGN GET_CTX_PARAMS [ algorithm-id ] SIGN DIGEST_SIGN estimate SIGN DIGEST_SIGN CMP info: sending IR CMP error: Connection timed out:calling connect() CMP error: connect error CMP error: Connection timed out:calling connect(10.33.123.231, 8081) CMP error: connect error CMP error: transfer error:request sent: IR, expected response: IP RSA FREE RSA FREE RAND FREE RAND FREE PROVIDER TEARDOWN

gotthardp commented 11 months ago

Yeah. The error above is connect error because the Connection timed out, so this is connectivity related, not a TPM2 issue. It seems the tpm2 provider works correctly in this case.

sumanth797 commented 11 months ago

The connection timeout error is expected, but my doubt is why through the openssl cmp command it is trying to send IR and failing to connect which is expected, and when i'm trying to achieve the same in c++ programatically, it fails to send IR. O/p is: IR is failed failed code is -1 failed cmp ctx CMP error: missing private key CMP error: RSA lib CMP error: EVP lib CMP error: error creating certreq Anything wrong in our program or anything we are missing while loading the providers or setting of the cmp ctx using apis?

gotthardp commented 11 months ago

As I wrote, the passwords are wrong. I tried to build and execute the code and reached the connectivity error. I didn't get the key related error.

sumanth797 commented 11 months ago

Hi, This is how I generated the key pair and persisted it with the correct password.

echo Jz7AATQApZAx3OdGrikOqohgI6Ux5MGktKbhiExFJdbvLFE9dlPLuaRmA4VYg8fLcBhFDQaAcmpxZvguAqbwCM3ZZVhN1iSlhAZD75SYuo4o8n9tm5cm44OAnLB7M5m2QQkdZZqsMQ6FpPOAHBFoEwI2Y1PFAB0dponCuAUIfPSlZXgmKILvJvc54HQALadted4C9gbrYS6ZyjfU9GNNckaoegqVWnFSvoCDEcaRTeExkKeHBZNfkIP79VPZYSh |tpm2 createprimary -C e -G rsa2048 -a 'restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth' -u - -c /working_dir/endorsementkey.ctx -P GosKS1xXvgkM6bSm -p qx2lAO8Jf4RbXJBb

tpm2_evictcontrol -C o -c /working_dir/endorsementkey.ctx 0x81010001 -P vMHuwlrSsGXNSXER

tpm2_create -C 0x81010001 -a 'fixedtpm|fixedparent|sensitivedataorigin|userwithauth|decrypt|sign' -u /working_dir/vendorkey.pub -r /working_dir/vendorkey.priv -P qx2lAO8Jf4RbXJBb -p Aw2WLz9bHAideywh

tpm2_load -C 0x81010001 -u /working_dir/vendorkey.pub -r /working_dir/vendorkey.priv -c /working_dir/vendorkey.ctx -P qx2lAO8Jf4RbXJBb

tpm2_evictcontrol -C o -c /working_dir/vendorkey.ctx 0x81010002 -P vMHuwlrSsGXNSXER

And CSR File is generated using,

openssl req -new -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -key handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh -out /working_dir/vendorkey.csr -config /config/csr.cnf

And tpm_private_key is generated using,

openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -out tpm_privatekey.pem -in handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh

And tpm_public_key is generated using,

openssl rsa -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -pubout -out tpm_publickey.pem -in handle:0x81010002?pass -passin pass:Aw2WLz9bHAideywh

And serialNo.pem is generated using,

We have serialNo.pem generated by using the vendorkey.csr from above and then CSR File is sent to the ca server to get it. And CA Server directly we cannot access it directly.

And rsa_private_key.pem,

openssl genrsa -out rsa-private.pem 2048

Attached the keys and pem files generated in the below link,

TPM_PEM_FILES.zip Link for files: https://github.com/tpm2-software/tpm2-openssl/files/13295681/TPM_PEM_FILES.zip

Prerequisite for sending IR using cmp:

  • We have generated vendor key pair and stored in tpm, steps mentioned above.
  • We have serialNo.pem generated by using the vendorkey.csr from above and then CSR File is sent to the ca server to get serialNo.pem and then stored in nv_index for later use.
  • And we generated a rsa_private_key.pem which is used by application for connecting in TLS Mode.
  • We are using OSSL_STORE apis to fetch the EVP_PKEY data later for setting the cmp_ctx

This is the password "Aw2WLz9bHAideywh" that is used in the code and also the command. Whatever the password you have mentioned earlier is incorrect password, that I'm aware because i haven't shared the exact password with you i just gave a reference on how we are generating the key pair in another machine. Now, I have shared with exact password on the machine I'm testing and also the key pair generation above.

cmp command: openssl cmp -provider-path /usr/lib64/ossl-packages/ -provider tpm2 -provider default -propquery '?provider=tpm2,tpm2.digest!=yes' -cmd ir -server 10.33.123.231:8081/pkix/ -recipient "/CN=CMPserver" -cert /working_dir/serialNo.pem -key handle:0x81010002?pass -keypass pass:Aw2WLz9bHAideywh -subject "/CN=Client" -certout test-my-cert.pem -cacertsout test-my-ca.pem

I tested with the command and IR is sent, but when tested through the code, it says missing Private key.

gotthardp commented 11 months ago

The code you sent looks good. I don't see anything wrong.

sumanth797 commented 11 months ago

So, what can I conclude now? I'm not sure how to proceed. can you tell me how you tested it?

gotthardp commented 11 months ago

If you want to continue, you should write a single script that (assuming an empty TPM) will execute all the preparatory steps automatically with the correct passwords, etc. Not a text guide, a fully automated shell script (and the .c file). Then we could both build the .c file, run the script and see whether and how the results differ.

sumanth797 commented 11 months ago

Hi, I'm Sharing the script files and cpp file in zip format.

TPM_QUERY.zip

tpm_script.sh will do the generation of keys and clear_tpm.sh will do the tpm_clear operations.

Ensure no tpm persistent handles are present. If present, clear them and run the tpm_script.sh

change the path in the tpm_script for storing the files.

Then generate private key using,

openssl genrsa -out rsa_private_key.pem 2048

Then execute the cpp file

g++ opensource_tpm.cpp -o opensource_tpm -lssl -lcrypto

After it is done, run clear_tpm.sh to remove the persistent handles to redo the operation again from generation of keys.

certificate is not shared because, it will be different in your machine and ca server is not directly accessible. Can you share the command on how you are generating the certificate in your machine for testing?

sumanth797 commented 11 months ago

Hi @gotthardp ,

Can you help us here for the above issue? As you confirmed that the shared code is working in your machine. Can you explain what are we doing wrong or missing details in the code for performing IR?

These are the error logs in my machine.

807B57B2807F0000:error:020000B3:rsa routines:rsa_ossl_private_encrypt:missing private key:crypto/rsa/rsa_ossl.c:332: 807B57B2807F0000:error:1C880004:Provider routines:rsa_sign:RSA lib:providers/implementations/signature/rsa_sig.c:588: 807B57B2807F0000:error:06880006:asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:crypto/asn1/a_sign.c:284: 807B57B2807F0000:error:1D00007F:CMP routines:ossl_cmp_msg_protect:error protecting message:crypto/cmp/cmp_protect.c:332: 807B57B2807F0000:error:1D0000A3:CMP routines:ossl_cmp_certreq_new:error creating certreq:crypto/cmp/cmp_msg.c:439: