tpm2-software / tpm2-openssl

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

CSR, Certificate validation error #124

Open hoinmic opened 1 month ago

hoinmic commented 1 month ago

Hello together

I am stuck with OpenSSL at one point. We send a CSR from a TPM to the PKI and the PKI sends back a certificate. Unfortunately, the certificate verification fails. The PKI has existed for some time and must continue to be used. The PKI signs the certificates with a SHA512. The TPM, for its part, can use algorithms up to sha384 ( TPM Infineon 9673 ). The problem is that openssl uses the TPM (which does not support this algorithm) to validate the certificate. In my opinion, OpenSSL could do this without the TPM.

I have now tried a few things with the propquery. For example:

...
-provider tpm2 -provider default -propquery ?provider=tpm2,provider-signature!=yes
...

But I always failed.

The procedure is as follows:

.....
openssl req -provider tpm2 -new \
-subj $csr_subject \
-key handle:$handle \
-out $client_crs_file \
-sha384

openssl cmp -provider tpm2 -provider default -propquery ?provider=tpm2,provider-signature!=yes \
-cmd ir \
-config "" \
-server 192.168.251.40:80 \
-path /api/cmp \
-unprotected_requests \
-unprotected_errors \
-srvcert IssuingCA2018.cacert.pem \
-subject $csr_subject \
-csr $client_crs_file \
-certout $received_cert \
-extracertsout $received_extracert \
-newkey handle:$handle \
-verbosity 8

The CMP IR displays the following response:

CMP info: sending IR
CMP info: received IP
CMP DEBUG: validating CMP message
WARNING:esys:/usr/src/debug/tpm2-tss/4.0.1/src/tss2-esys/api/Esys_LoadExternal.c:314:Esys_LoadExternal_Finish() Received TPM Error
ERROR:esys:/usr/src/debug/tpm2-tss/4.0.1/src/tss2-esys/api/Esys_LoadExternal.c:108:Esys_LoadExternal() Esys Finish ErrorCode (0x000002e6)
CMP warning: CMP message signature verification failed
CMP error: cannot load key:742 tpm:parameter(2):curve not supported
CMP error: EVP lib
CMP error: error validating signature

Does anyone have any ideas what we could change or what we are doing wrong?

DDvO commented 1 month ago

We meanwhile figured that the issue is not really with with the digest but regarding the curve being used for EC keys.

The tpm2 provider is being used successfully for producing a ECDSA self-signature of the CSR, with 384 bits, but when the CMP client obtains a response message signed using ECDSA with 521 bits, attempting to verify the signature with the tpm2 provider being enables fails because such long keys are not supported.

Actually there is no need to use the provider for signature validation as this just requires the public key, and for performance reason this should not really be done. Is there a way, of excluding via a property query specifically the signature verification operation?

Unfortunately, tpm2 documentation on the possible query values is non-existing/incomplete: docs/initialization.md just gives an example: -propqueryprovider=tpm2,tpm2.digest!=yes A view at src/tpm2-provider.c reveals that there is also signature, but not verification.

DDvO commented 1 month ago

Does it make sense after all that the provider offers support for verifying signatures? Maybe it should simply not offer this operation at all.

hoinmic commented 1 month ago

I also think that the provider should not offer signature verification.

In case someone runs into the same situation. With support from @DDvO we have found out the following workaround:

# Command is executed to generate a request with support of tpm device. The command 
# is stopped abruptly when the dummy file is consulted. At this point, the request (req.der) has already
# been created.
touch dummyfile
openssl cmp -provider tpm2 -provider default \
-cmd ir \
-config "" \
-server 192.168.251.40:80 \
-path /api/cmp \
-unprotected_requests \
-unprotected_errors \
-srvcert IssuingCA2018.cacert.pem \
-subject $csr_subject \
-certout $received_cert \
-extracertsout $received_extracert \
-newkey handle:$handle \
-verbosity 8 \
-reqout req.der \
-rspin dummyfile

# Command is executed to send the previously generated request (req.der) without support of a tpm device.
openssl cmp \
-cmd ir \
-config "" \
-server 192.168.251.40:80 \
-path /api/cmp \
-unprotected_requests \
-unprotected_errors \
-srvcert IssuingCA2018.cacert.pem \
-subject $csr_subject \
-certout $received_cert \
-extracertsout $received_extracert \
-newkey pubkey.pem \
-verbosity 8 \
-reqin req.der \
-popo -1 \
-disable_confirm