From 9198ea5057126b803bfde06727f74fbe0cde689eeae101736f6cc94ebe99442b Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Thu, 24 Nov 2022 10:28:59 +0000 Subject: [PATCH] Accepting request 1037119 from home:pmonrealgonzalez:branches:security - Build with OpenSSL 3.0 deprecated functions until fixed upstream in the next version update [bsc#1205042] * ibmtss-openssl3-deprecation.patch - Add upstream patches to fix build with OpenSSL 3.0 * ibmtss-regtests-Update-openssl-key-generation-for-3.0.0.patch * ibmtss-utils-Update-certifyx509-for-Openssl-3.0.0.patch * ibmtss-utils-Remove-unused-variables-from-certifyx509.patch * ibmtss-tss-Port-HMAC-operations-to-openssl-3.0.patch * ibmtss-utils-Port-to-openssl-3.0.0-replaces-RSA-with-EVP_PK.patch OBS-URL: https://build.opensuse.org/request/show/1037119 OBS-URL: https://build.opensuse.org/package/show/security/ibmtss?expand=0&rev=43 --- ibmtss-openssl3-deprecation.patch | 26 + ...ate-openssl-key-generation-for-3.0.0.patch | 453 ++++++ ...-Port-HMAC-operations-to-openssl-3.0.patch | 237 +++ ...enssl-3.0.0-replaces-RSA-with-EVP_PK.patch | 1399 ++++++++++++++++ ...ve-unused-variables-from-certifyx509.patch | 51 + ...Update-certifyx509-for-Openssl-3.0.0.patch | 1447 +++++++++++++++++ ibmtss.changes | 13 + ibmtss.spec | 8 +- 8 files changed, 3633 insertions(+), 1 deletion(-) create mode 100644 ibmtss-openssl3-deprecation.patch create mode 100644 ibmtss-regtests-Update-openssl-key-generation-for-3.0.0.patch create mode 100644 ibmtss-tss-Port-HMAC-operations-to-openssl-3.0.patch create mode 100644 ibmtss-utils-Port-to-openssl-3.0.0-replaces-RSA-with-EVP_PK.patch create mode 100644 ibmtss-utils-Remove-unused-variables-from-certifyx509.patch create mode 100644 ibmtss-utils-Update-certifyx509-for-Openssl-3.0.0.patch diff --git a/ibmtss-openssl3-deprecation.patch b/ibmtss-openssl3-deprecation.patch new file mode 100644 index 0000000..2a7949c --- /dev/null +++ b/ibmtss-openssl3-deprecation.patch @@ -0,0 +1,26 @@ +Index: ibmtss-1.6.0/build.sh +=================================================================== +--- ibmtss-1.6.0.orig/build.sh ++++ ibmtss-1.6.0/build.sh +@@ -13,7 +13,7 @@ cleanup() { + } + + CC="${CC:-gcc}" +-CFLAGS="${CFLAGS:--Wformat -Werror=format-security -Werror=implicit-function-declaration -Werror=return-type -fno-common}" ++CFLAGS="${CFLAGS:--Wformat -Werror=format-security -Werror=implicit-function-declaration -Werror=return-type -fno-common -Wno-error=deprecated-declarations}" + PREFIX="${PREFIX:-$HOME/tpm2}" + + export LD_LIBRARY_PATH="$PREFIX/lib64:$PREFIX/lib:/usr/local/lib64:/usr/local/lib" +Index: ibmtss-1.6.0/configure.ac +=================================================================== +--- ibmtss-1.6.0.orig/configure.ac ++++ ibmtss-1.6.0/configure.ac +@@ -71,7 +71,7 @@ AC_ARG_ENABLE(debug, + + # Linux requires -DTPM_POSIX + case $host_os in +- linux-*) CFLAGS="-DTPM_POSIX $CFLAGS" ;; ++ linux-*) CFLAGS="-DTPM_POSIX $CFLAGS -Wno-error=deprecated-declarations" ;; + esac + + AC_ARG_ENABLE(tpm-2.0, diff --git a/ibmtss-regtests-Update-openssl-key-generation-for-3.0.0.patch b/ibmtss-regtests-Update-openssl-key-generation-for-3.0.0.patch new file mode 100644 index 0000000..f4240ae --- /dev/null +++ b/ibmtss-regtests-Update-openssl-key-generation-for-3.0.0.patch @@ -0,0 +1,453 @@ +From f1c6b44f95392c156b235d42bccc8235ee24bb6f Mon Sep 17 00:00:00 2001 +From: Ken Goldman +Date: Wed, 11 Aug 2021 18:22:41 -0400 +Subject: regtests: Update openssl key generation for 3.0.0 + +OpenSSL 3.0.0 used a different pem and der key format. Update the +command line calls. Bypass the tests that use these functions for +mbedtls, which does not support the new format. + +Signed-off-by: Ken Goldman + +diff --git a/utils/regtests/testdup.sh b/utils/regtests/testdup.sh +index eeca02f..e849e44 100755 +--- a/utils/regtests/testdup.sh ++++ b/utils/regtests/testdup.sh +@@ -7,7 +7,7 @@ + # Written by Ken Goldman # + # IBM Thomas J. Watson Research Center # + # # +-# (c) Copyright IBM Corporation 2015 - 2020 # ++# (c) Copyright IBM Corporation 2015 - 2021 # + # # + # All rights reserved. # + # # +@@ -215,7 +215,12 @@ echo "" + + if [ ${CRYPTOLIBRARY} == "openssl" ]; then + echo "generate the RSA signing key with openssl" +- openssl genrsa -out tmpprivkey.pem -aes256 -passout pass:rrrr 2048 > run.out 2>&1 ++ ++ openssl genpkey -out tmpprivkey.pem -outform pem -aes-256-cbc -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -pass pass:rrrr > run.out 2>&1 ++ ++# The following worked up to Openssl 3.0.0. The key generation ++# remains here for when mbedtls is updated, but the tests are now ++# if'ed out + + elif [ ${CRYPTOLIBRARY} == "mbedtls" ]; then + echo "Generate the RSA signing key with openssl" +@@ -232,22 +237,24 @@ else + exit 255 + fi + +-echo "load the ECC storage key 80000001" +-${PREFIX}load -hp 80000000 -pwdp sto -ipr storeeccnistp256priv.bin -ipu storeeccnistp256pub.bin > run.out +-checkSuccess $? ++if [ ${CRYPTOLIBRARY} == "openssl" ]; then + +-echo "Start an HMAC auth session" +-${PREFIX}startauthsession -se h > run.out +-checkSuccess $? ++ echo "load the ECC storage key 80000001" ++ ${PREFIX}load -hp 80000000 -pwdp sto -ipr storeeccnistp256priv.bin -ipu storeeccnistp256pub.bin > run.out ++ checkSuccess $? + +-for SESS in "" "-se0 02000000 1" +-do +- for HALG in ${ITERATE_ALGS} +- do ++ echo "Start an HMAC auth session" ++ ${PREFIX}startauthsession -se h > run.out ++ checkSuccess $? + +- for PARENT in 80000000 80000001 ++ for SESS in "" "-se0 02000000 1" ++ do ++ for HALG in ${ITERATE_ALGS} + do + ++ for PARENT in 80000000 80000001 ++ do ++ + echo "Import the signing key under the parent key ${PARENT} ${HALG}" + ${PREFIX}importpem -hp ${PARENT} -pwdp sto -ipem tmpprivkey.pem -pwdk rrrr -opu tmppub.bin -opr tmppriv.bin -halg ${HALG} > run.out + checkSuccess $? +@@ -268,9 +275,10 @@ do + ${PREFIX}flushcontext -ha 80000002 > run.out + checkSuccess $? + ++ done + done + done +-done ++fi + + echo "" + echo "Import PEM EC signing key under RSA and ECC storage key" +@@ -300,49 +308,53 @@ else + exit 255 + fi + +-for CURVE in "nistp256" "nistp384" +-do +- +- for SESS in "" "-se0 02000000 1" ++if [ ${CRYPTOLIBRARY} == "openssl" ]; then ++ ++ for CURVE in "nistp256" "nistp384" + do +- for HALG in ${ITERATE_ALGS} +- do + +- for PARENT in 80000000 80000001 ++ for SESS in "" "-se0 02000000 1" ++ do ++ for HALG in ${ITERATE_ALGS} + do + +- echo "Import the ${CURVE} signing key under the parent key ${PARENT} ${HALG}" +- ${PREFIX}importpem -hp ${PARENT} -pwdp sto -ipem tmpec${CURVE}privkey.pem -ecc -pwdk rrrr -opu tmppub.bin -opr tmppriv.bin -halg ${HALG} > run.out +- checkSuccess $? ++ for PARENT in 80000000 80000001 ++ do + +- echo "Load the TPM signing key" +- ${PREFIX}load -hp ${PARENT} -pwdp sto -ipu tmppub.bin -ipr tmppriv.bin > run.out +- checkSuccess $? ++ echo "Import the ${CURVE} signing key under the parent key ${PARENT} ${HALG}" ++ ${PREFIX}importpem -hp ${PARENT} -pwdp sto -ipem tmpec${CURVE}privkey.pem -ecc -pwdk rrrr -opu tmppub.bin -opr tmppriv.bin -halg ${HALG} > run.out ++ checkSuccess $? + +- echo "Sign the message ${HALG} ${SESS}" +- ${PREFIX}sign -hk 80000002 -salg ecc -pwdk rrrr -if policies/aaa -os tmpsig.bin -halg ${HALG} ${SESS} > run.out +- checkSuccess $? ++ echo "Load the TPM signing key" ++ ${PREFIX}load -hp ${PARENT} -pwdp sto -ipu tmppub.bin -ipr tmppriv.bin > run.out ++ checkSuccess $? + +- echo "Verify the signature ${HALG}" +- ${PREFIX}verifysignature -hk 80000002 -ecc -if policies/aaa -is tmpsig.bin -halg ${HALG} > run.out +- checkSuccess $? ++ echo "Sign the message ${HALG} ${SESS}" ++ ${PREFIX}sign -hk 80000002 -salg ecc -pwdk rrrr -if policies/aaa -os tmpsig.bin -halg ${HALG} ${SESS} > run.out ++ checkSuccess $? + +- echo "Flush the signing key" +- ${PREFIX}flushcontext -ha 80000002 > run.out +- checkSuccess $? ++ echo "Verify the signature ${HALG}" ++ ${PREFIX}verifysignature -hk 80000002 -ecc -if policies/aaa -is tmpsig.bin -halg ${HALG} > run.out ++ checkSuccess $? + ++ echo "Flush the signing key" ++ ${PREFIX}flushcontext -ha 80000002 > run.out ++ checkSuccess $? ++ ++ done + done + done + done +-done + +-echo "Flush the ECC storage key" +-${PREFIX}flushcontext -ha 80000001 > run.out +-checkSuccess $? ++ echo "Flush the ECC storage key" ++ ${PREFIX}flushcontext -ha 80000001 > run.out ++ checkSuccess $? + +-echo "Flush the auth session" +-${PREFIX}flushcontext -ha 02000000 > run.out +-checkSuccess $? ++ echo "Flush the auth session" ++ ${PREFIX}flushcontext -ha 02000000 > run.out ++ checkSuccess $? ++ ++fi + + echo "" + echo "Rewrap" +diff --git a/utils/regtests/testrsa.sh b/utils/regtests/testrsa.sh +index 4f76522..5ae0b29 100755 +--- a/utils/regtests/testrsa.sh ++++ b/utils/regtests/testrsa.sh +@@ -7,7 +7,7 @@ + # Written by Ken Goldman # + # IBM Thomas J. Watson Research Center # + # # +-# (c) Copyright IBM Corporation 2015 - 2020 # ++# (c) Copyright IBM Corporation 2015 - 2021 # + # # + # All rights reserved. # + # # +@@ -59,20 +59,25 @@ if [ ${CRYPTOLIBRARY} == "openssl" ]; then + do + + echo "Generate the RSA $BITS encryption key with openssl" +- openssl genrsa -out tmpkeypairrsa${BITS}.pem -aes256 -passout pass:rrrr ${BITS} > run.out 2>&1 ++ openssl genpkey -out tmpkeypairrsa${BITS}.pem -outform pem -aes-256-cbc -algorithm rsa -pkeyopt rsa_keygen_bits:${BITS} -pass pass:rrrr > run.out 2>&1 + + echo "Convert key pair to plaintext DER format" +- openssl rsa -inform pem -outform der -in tmpkeypairrsa${BITS}.pem -out tmpkeypairrsa${BITS}.der -passin pass:rrrr > run.out 2>&1 ++ openssl pkey -inform pem -in tmpkeypairrsa${BITS}.pem -outform der -out tmpkeypairrsa${BITS}.der -passin pass:rrrr > run.out 2>&1 + + done + ++ ++# The following worked up to Openssl 3.0.0. The key generation ++# remains here for when mbedtls is updated, but the tests are now ++# if'ed out ++ + elif [ ${CRYPTOLIBRARY} == "mbedtls" ]; then + + for BITS in 2048 3072 + do + + echo "Generate the RSA $BITS encryption key with openssl" +- openssl genrsa -out tmpkeypairrsaenc${BITS}.pem -aes256 -passout pass:rrrr ${BITS} > run.out 2>&1 ++ openssl genrsa -out tmpkeypairrsaenc${BITS}.pem -outform pem -aes-256-cbc -algorithm rsa -pkeyopt rsa_keygen_bits:${BITS} -pass:rrrr > run.out 2>&1 + + echo "Convert RSA $BITS key pair to plaintext DER format" + openssl rsa -in tmpkeypairrsaenc${BITS}.pem -passin pass:rrrr -outform der -out tmpkeypairrsa${BITS}.der > run.out 2>&1 +@@ -158,20 +163,22 @@ do + + done + +-echo "" +-echo "Import PEM RSA encryption key" +-echo "" ++if [ ${CRYPTOLIBRARY} == "openssl" ]; then + +-echo "Start an HMAC auth session" +-${PREFIX}startauthsession -se h > run.out +-checkSuccess $? ++ echo "" ++ echo "Import PEM RSA encryption key" ++ echo "" + +-for BITS in 2048 3072 +-do ++ echo "Start an HMAC auth session" ++ ${PREFIX}startauthsession -se h > run.out ++ checkSuccess $? + +- for SESS in "" "-se0 02000000 1" ++ for BITS in 2048 3072 + do + ++ for SESS in "" "-se0 02000000 1" ++ do ++ + echo "Import the $BITS encryption key under the primary key" + ${PREFIX}importpem -hp 80000000 -den -pwdp sto -ipem tmpkeypairrsa${BITS}.pem -pwdk rrrr -opu tmppub.bin -opr tmppriv.bin > run.out + checkSuccess $? +@@ -201,97 +208,98 @@ do + ${PREFIX}flushcontext -ha 80000001 > run.out + checkSuccess $? + ++ done ++ + done + +-done ++ echo "Flush the session" ++ ${PREFIX}flushcontext -ha 02000000 > run.out ++ checkSuccess $? + +-echo "Flush the session" +-${PREFIX}flushcontext -ha 02000000 > run.out +-checkSuccess $? ++ echo "" ++ echo "Import PEM RSA encryption key userWithAuth test" ++ echo "" + +-echo "" +-echo "Import PEM RSA encryption key userWithAuth test" +-echo "" ++ echo "Import the RSA 2048 encryption key under the primary key 80000000" ++ ${PREFIX}importpem -hp 80000000 -den -pwdp sto -ipem tmpkeypairrsa2048.pem -pwdk rrrr -opu tmppub.bin -opr tmppriv.bin > run.out ++ checkSuccess $? + +-echo "Import the RSA 2048 encryption key under the primary key 80000000" +-${PREFIX}importpem -hp 80000000 -den -pwdp sto -ipem tmpkeypairrsa2048.pem -pwdk rrrr -opu tmppub.bin -opr tmppriv.bin > run.out +-checkSuccess $? ++ echo "Load the RSA 2048 encryption key 80000001" ++ ${PREFIX}load -hp 80000000 -pwdp sto -ipu tmppub.bin -ipr tmppriv.bin > run.out ++ checkSuccess $? + +-echo "Load the RSA 2048 encryption key 80000001" +-${PREFIX}load -hp 80000000 -pwdp sto -ipu tmppub.bin -ipr tmppriv.bin > run.out +-checkSuccess $? ++ echo "RSA encrypt with the encryption key" ++ ${PREFIX}rsaencrypt -hk 80000001 -id policies/aaa -oe enc.bin > run.out ++ checkSuccess $? + +-echo "RSA encrypt with the encryption key" +-${PREFIX}rsaencrypt -hk 80000001 -id policies/aaa -oe enc.bin > run.out +-checkSuccess $? ++ echo "RSA decrypt with the decryption key and password" ++ ${PREFIX}rsadecrypt -hk 80000001 -pwdk rrrr -ie enc.bin -od dec.bin > run.out ++ checkSuccess $? + +-echo "RSA decrypt with the decryption key and password" +-${PREFIX}rsadecrypt -hk 80000001 -pwdk rrrr -ie enc.bin -od dec.bin > run.out +-checkSuccess $? ++ echo "Flush the encryption key" ++ ${PREFIX}flushcontext -ha 80000001 > run.out ++ checkSuccess $? + +-echo "Flush the encryption key" +-${PREFIX}flushcontext -ha 80000001 > run.out +-checkSuccess $? ++ echo "Import the RSA 2048 encryption key under the primary key, userWithAuth false" ++ ${PREFIX}importpem -hp 80000000 -si -pwdp sto -ipem tmpkeypairrsa2048.pem -pwdk rrrr -uwa -opu tmppub.bin -opr tmppriv.bin > run.out ++ checkSuccess $? + +-echo "Import the RSA 2048 encryption key under the primary key, userWithAuth false" +-${PREFIX}importpem -hp 80000000 -si -pwdp sto -ipem tmpkeypairrsa2048.pem -pwdk rrrr -uwa -opu tmppub.bin -opr tmppriv.bin > run.out +-checkSuccess $? ++ echo "Load the RSA 2048 encryption key" ++ ${PREFIX}load -hp 80000000 -pwdp sto -ipu tmppub.bin -ipr tmppriv.bin > run.out ++ checkSuccess $? + +-echo "Load the RSA 2048 encryption key" +-${PREFIX}load -hp 80000000 -pwdp sto -ipu tmppub.bin -ipr tmppriv.bin > run.out +-checkSuccess $? ++ echo "RSA decrypt with the decryption key and password - should fail" ++ ${PREFIX}rsadecrypt -hk 80000001 -pwdk rrrr -ie enc.bin -od dec.bin > run.out ++ checkFailure $? + +-echo "RSA decrypt with the decryption key and password - should fail" +-${PREFIX}rsadecrypt -hk 80000001 -pwdk rrrr -ie enc.bin -od dec.bin > run.out +-checkFailure $? ++ echo "Flush the encryption key" ++ ${PREFIX}flushcontext -ha 80000001 > run.out ++ checkSuccess $? + +-echo "Flush the encryption key" +-${PREFIX}flushcontext -ha 80000001 > run.out +-checkSuccess $? ++ echo "" ++ echo "Loadexternal DER encryption key" ++ echo "" + ++ for BITS in 2048 3072 ++ do + +-echo "" +-echo "Loadexternal DER encryption key" +-echo "" ++ echo "Start an HMAC auth session" ++ ${PREFIX}startauthsession -se h > run.out ++ checkSuccess $? + +-for BITS in 2048 3072 +-do ++ for SESS in "" "-se0 02000000 1" ++ do + +- echo "Start an HMAC auth session" +- ${PREFIX}startauthsession -se h > run.out +- checkSuccess $? ++ echo "Load the openssl key pair in the NULL hierarchy 80000001" ++ ${PREFIX}loadexternal -den -ider tmpkeypairrsa${BITS}.der -pwdk rrrr > run.out ++ checkSuccess $? + +- for SESS in "" "-se0 02000000 1" +- do ++ echo "RSA encrypt with the encryption key" ++ ${PREFIX}rsaencrypt -hk 80000001 -id policies/aaa -oe enc.bin > run.out ++ checkSuccess $? + +- echo "Load the openssl key pair in the NULL hierarchy 80000001" +- ${PREFIX}loadexternal -den -ider tmpkeypairrsa${BITS}.der -pwdk rrrr > run.out +- checkSuccess $? ++ echo "RSA decrypt with the decryption key ${SESS}" ++ ${PREFIX}rsadecrypt -hk 80000001 -pwdk rrrr -ie enc.bin -od dec.bin ${SESS} > run.out ++ checkSuccess $? + +- echo "RSA encrypt with the encryption key" +- ${PREFIX}rsaencrypt -hk 80000001 -id policies/aaa -oe enc.bin > run.out +- checkSuccess $? ++ echo "Verify the decrypt result" ++ tail -c 3 dec.bin > tmp.bin ++ diff policies/aaa tmp.bin > run.out ++ checkSuccess $? + +- echo "RSA decrypt with the decryption key ${SESS}" +- ${PREFIX}rsadecrypt -hk 80000001 -pwdk rrrr -ie enc.bin -od dec.bin ${SESS} > run.out +- checkSuccess $? ++ echo "Flush the encryption key" ++ ${PREFIX}flushcontext -ha 80000001 > run.out ++ checkSuccess $? + +- echo "Verify the decrypt result" +- tail -c 3 dec.bin > tmp.bin +- diff policies/aaa tmp.bin > run.out +- checkSuccess $? ++ done + +- echo "Flush the encryption key" +- ${PREFIX}flushcontext -ha 80000001 > run.out ++ echo "Flush the session" ++ ${PREFIX}flushcontext -ha 02000000 > run.out + checkSuccess $? + + done + +- echo "Flush the session" +- ${PREFIX}flushcontext -ha 02000000 > run.out +- checkSuccess $? +- +-done ++fi + + echo "" + echo "Encrypt with OpenSSL OAEP, decrypt with TPM" +diff --git a/utils/regtests/testsalt.sh b/utils/regtests/testsalt.sh +index 1bdc1a7..e0c3376 100755 +--- a/utils/regtests/testsalt.sh ++++ b/utils/regtests/testsalt.sh +@@ -91,16 +91,17 @@ echo "" + echo "Salt Session - Load External" + echo "" + +-echo "Create RSA and ECC key pairs in PEM format using openssl" ++echo "Create RSA key pair in DER format using openssl" + +-openssl genrsa -out tmpkeypairrsa.pem -aes256 -passout pass:rrrr 2048 > run.out 2>&1 +-openssl ecparam -name prime256v1 -genkey -noout -out tmpkeypairecc.pem > run.out 2>&1 ++openssl genpkey -out tmpkeypairrsa.der -outform der -aes-256-cbc -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -pass pass:rrrr > run.out 2>&1 + ++echo "Create ECC key pair in PEM format using openssl" + echo "Convert key pair to plaintext DER format" + +-openssl rsa -inform pem -outform der -in tmpkeypairrsa.pem -out tmpkeypairrsa.der -passin pass:rrrr > run.out 2>&1 ++openssl ecparam -name prime256v1 -genkey -noout -out tmpkeypairecc.pem > run.out 2>&1 + openssl ec -inform pem -outform der -in tmpkeypairecc.pem -out tmpkeypairecc.der -passin pass:rrrr > run.out 2>&1 + ++ + for HALG in ${ITERATE_ALGS} + do + +diff --git a/utils/regtests/testsign.sh b/utils/regtests/testsign.sh +index edfa014..3002ceb 100755 +--- a/utils/regtests/testsign.sh ++++ b/utils/regtests/testsign.sh +@@ -47,11 +47,9 @@ echo "" + for BITS in 2048 3072 + do + +- echo "Create an RSA $BITS key pair in PEM format using openssl" +- openssl genrsa -out tmpkeypairrsa${BITS}.pem -aes256 -passout pass:rrrr 2048 > run.out 2>&1 ++ echo "Create an RSA $BITS key pair in DER format using openssl" + +- echo "Convert RSA $BITS key pair to plaintext DER format" +- openssl rsa -inform pem -outform der -in tmpkeypairrsa${BITS}.pem -out tmpkeypairrsa${BITS}.der -passin pass:rrrr > run.out 2>&1 ++ openssl genpkey -out tmpkeypairrsa${BITS}.der -outform der -aes-256-cbc -algorithm rsa -pkeyopt rsa_keygen_bits:${BITS} -pass pass:rrrr > run.out 2>&1 + + echo "Load the RSA $BITS signing key under the primary key" + ${PREFIX}load -hp 80000000 -ipr signrsa${BITS}priv.bin -ipu signrsa${BITS}pub.bin -pwdp sto > run.out +-- +2.38.0 + diff --git a/ibmtss-tss-Port-HMAC-operations-to-openssl-3.0.patch b/ibmtss-tss-Port-HMAC-operations-to-openssl-3.0.patch new file mode 100644 index 0000000..4d18160 --- /dev/null +++ b/ibmtss-tss-Port-HMAC-operations-to-openssl-3.0.patch @@ -0,0 +1,237 @@ +From 6e22032d637ea8c28cf84efa837a22909873466a Mon Sep 17 00:00:00 2001 +From: Ken Goldman +Date: Fri, 10 Sep 2021 16:33:10 -0400 +Subject: tss: Port HMAC operations to openssl 3.0 + +Replace the deprecated APIs. + +Signed-off-by: Ken Goldman + +diff --git a/utils/tsscrypto.c b/utils/tsscrypto.c +index 35f0ed3..c2ce01a 100644 +--- a/utils/tsscrypto.c ++++ b/utils/tsscrypto.c +@@ -79,6 +79,7 @@ extern int tssVerbose; + + /* local prototypes */ + ++static TPM_RC TSS_Hash_GetOsslString(const char **str, TPMI_ALG_HASH hashAlg); + static TPM_RC TSS_Hash_GetMd(const EVP_MD **md, + TPMI_ALG_HASH hashAlg); + +@@ -129,36 +130,51 @@ TPM_RC TSS_Crypto_Init(void) + Digests + */ + +-static TPM_RC TSS_Hash_GetMd(const EVP_MD **md, +- TPMI_ALG_HASH hashAlg) ++/* TSS_Hash_GetString() maps from the TCG hash algorithm to the OpenSSL string */ ++ ++static TPM_RC TSS_Hash_GetOsslString(const char **str, TPMI_ALG_HASH hashAlg) + { +- TPM_RC rc = 0; ++ TPM_RC rc = 0; + +- if (rc == 0) { +- switch (hashAlg) { ++ switch (hashAlg) { + #ifdef TPM_ALG_SHA1 +- case TPM_ALG_SHA1: +- *md = EVP_get_digestbyname("sha1"); +- break; ++ case TPM_ALG_SHA1: ++ *str = "sha1"; ++ break; + #endif +-#ifdef TPM_ALG_SHA256 +- case TPM_ALG_SHA256: +- *md = EVP_get_digestbyname("sha256"); +- break; ++#ifdef TPM_ALG_SHA256 ++ case TPM_ALG_SHA256: ++ *str = "sha256"; ++ break; + #endif + #ifdef TPM_ALG_SHA384 +- case TPM_ALG_SHA384: +- *md = EVP_get_digestbyname("sha384"); +- break; ++ case TPM_ALG_SHA384: ++ *str = "sha384"; ++ break; + #endif + #ifdef TPM_ALG_SHA512 +- case TPM_ALG_SHA512: +- *md = EVP_get_digestbyname("sha512"); +- break; ++ case TPM_ALG_SHA512: ++ *str = "sha512"; ++ break; + #endif +- default: +- rc = TSS_RC_BAD_HASH_ALGORITHM; +- } ++ default: ++ *str = NULL; ++ rc = TSS_RC_BAD_HASH_ALGORITHM; ++ } ++ return rc; ++} ++ ++static TPM_RC TSS_Hash_GetMd(const EVP_MD **md, ++ TPMI_ALG_HASH hashAlg) ++{ ++ TPM_RC rc = 0; ++ const char *str = NULL; ++ ++ if (rc == 0) { ++ rc = TSS_Hash_GetOsslString(&str, hashAlg); ++ } ++ if (rc == 0) { ++ *md = EVP_get_digestbyname(str); + } + return rc; + } +@@ -175,37 +191,84 @@ TPM_RC TSS_HMAC_Generate_valist(TPMT_HA *digest, /* largest size of a digest */ + TPM_RC rc = 0; + int irc = 0; + int done = FALSE; +- const EVP_MD *md; /* message digest method */ +-#if OPENSSL_VERSION_NUMBER < 0x10100000 ++ uint8_t *buffer; /* segment to hash */ ++ int length; /* segment to hash */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000 + HMAC_CTX ctx; ++ const EVP_MD *md = NULL; /* message digest method */ ++#elif OPENSSL_VERSION_NUMBER < 0x30000000 ++ HMAC_CTX *ctx = NULL; ++ const EVP_MD *md = NULL; /* message digest method */ + #else +- HMAC_CTX *ctx; ++ EVP_MAC *mac = NULL; ++ EVP_MAC_CTX *ctx = NULL; ++ const char *algString = NULL; ++ OSSL_PARAM params[2]; ++ size_t outLength; + #endif +- int length; +- uint8_t *buffer; +- ++ ++ /* initialize the HMAC context */ + #if OPENSSL_VERSION_NUMBER < 0x10100000 + HMAC_CTX_init(&ctx); ++#elif OPENSSL_VERSION_NUMBER < 0x30000000 ++ if (rc == 0) { ++ ctx = HMAC_CTX_new(); ++ if (ctx == NULL) { ++ if (tssVerbose) printf("TSS_Hash_Generate_valist: HMAC_CTX_new failed\n"); ++ rc = TSS_RC_OUT_OF_MEMORY; ++ } ++ } + #else +- ctx = HMAC_CTX_new(); ++ if (rc == 0) { ++ mac = EVP_MAC_fetch(NULL, "hmac", NULL); ++ if (mac == NULL) { ++ if (tssVerbose) printf("TSS_Hash_Generate_valist: EVP_MAC_new failed\n"); ++ rc = TSS_RC_OUT_OF_MEMORY; ++ } ++ } ++ if (rc == 0) { ++ ctx = EVP_MAC_CTX_new(mac); ++ if (ctx == NULL) { ++ if (tssVerbose) printf("TSS_Hash_Generate_valist: EVP_MAC_CTX_new failed\n"); ++ rc = TSS_RC_OUT_OF_MEMORY; ++ } ++ } + #endif ++ ++ /* get the message digest */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + if (rc == 0) { + rc = TSS_Hash_GetMd(&md, digest->hashAlg); + } ++#else ++ /* map algorithm to string */ ++ if (rc == 0) { ++ rc = TSS_Hash_GetOsslString(&algString, digest->hashAlg); ++ } ++#endif ++ ++ /* initialize the MAC context */ + if (rc == 0) { + #if OPENSSL_VERSION_NUMBER < 0x10100000 + irc = HMAC_Init_ex(&ctx, + hmacKey->b.buffer, hmacKey->b.size, /* HMAC key */ + md, /* message digest method */ + NULL); +-#else ++#elif OPENSSL_VERSION_NUMBER < 0x30000000 + irc = HMAC_Init_ex(ctx, + hmacKey->b.buffer, hmacKey->b.size, /* HMAC key */ + md, /* message digest method */ + NULL); ++#else ++ params[0] = OSSL_PARAM_construct_utf8_string("digest", (char *)algString, 0); ++ params[1] = OSSL_PARAM_construct_end(); ++ irc = EVP_MAC_init(ctx, ++ hmacKey->b.buffer, hmacKey->b.size, /* HMAC key */ ++ params); /* message digest method */ + #endif +- +- if (irc == 0) { ++ ++ if (irc != 1) { ++ if (tssVerbose) printf("TSS_HMAC_Generate: HMAC Init failed\n"); + rc = TSS_RC_HMAC; + } + } +@@ -220,11 +283,13 @@ TPM_RC TSS_HMAC_Generate_valist(TPMT_HA *digest, /* largest size of a digest */ + else { + #if OPENSSL_VERSION_NUMBER < 0x10100000 + irc = HMAC_Update(&ctx, buffer, length); +-#else ++#elif OPENSSL_VERSION_NUMBER < 0x30000000 + irc = HMAC_Update(ctx, buffer, length); ++#else ++ irc = EVP_MAC_update(ctx, buffer, length); + #endif +- if (irc == 0) { +- if (tssVerbose) printf("TSS_HMAC_Generate: HMAC_Update failed\n"); ++ if (irc != 1) { ++ if (tssVerbose) printf("TSS_HMAC_Generate: HMAC Update failed\n"); + rc = TSS_RC_HMAC; + } + } +@@ -237,18 +302,24 @@ TPM_RC TSS_HMAC_Generate_valist(TPMT_HA *digest, /* largest size of a digest */ + if (rc == 0) { + #if OPENSSL_VERSION_NUMBER < 0x10100000 + irc = HMAC_Final(&ctx, (uint8_t *)&digest->digest, NULL); +-#else ++#elif OPENSSL_VERSION_NUMBER < 0x30000000 + irc = HMAC_Final(ctx, (uint8_t *)&digest->digest, NULL); ++#else ++ irc = EVP_MAC_final(ctx, (uint8_t *)&digest->digest, &outLength, sizeof(digest->digest)); + #endif + if (irc == 0) { ++ if (tssVerbose) printf("TSS_HMAC_Generate: HMAC Final failed\n"); + rc = TSS_RC_HMAC; + } + } + #if OPENSSL_VERSION_NUMBER < 0x10100000 + HMAC_CTX_cleanup(&ctx); +-#else ++#elif OPENSSL_VERSION_NUMBER < 0x30000000 + HMAC_CTX_free(ctx); +-#endif ++#else ++ EVP_MAC_CTX_free(ctx); ++ EVP_MAC_free(mac); ++ #endif + return rc; + } + +-- +2.38.0 + diff --git a/ibmtss-utils-Port-to-openssl-3.0.0-replaces-RSA-with-EVP_PK.patch b/ibmtss-utils-Port-to-openssl-3.0.0-replaces-RSA-with-EVP_PK.patch new file mode 100644 index 0000000..cef9be1 --- /dev/null +++ b/ibmtss-utils-Port-to-openssl-3.0.0-replaces-RSA-with-EVP_PK.patch @@ -0,0 +1,1399 @@ +From 65c77e87c248cfc4a54eddbf159e89c1ff088714 Mon Sep 17 00:00:00 2001 +From: Ken Goldman +Date: Fri, 17 Sep 2021 19:04:39 -0400 +Subject: utils: Port to openssl 3.0.0 replaces RSA with + EVP_PKEY + +The RSA structure is deprecated. This flows through all the +utilities, including the X509 public key handling, the PEM and DER +public and private key converters, the functions to convert to and +from the RSA bignums, the sign and encrypt functions. + +TODO are the equivalent updates for ECC and AES. + +Signed-off-by: Ken Goldman + +Index: ibmtss-1.6.0/utils/cryptoutils.c +=================================================================== +--- ibmtss-1.6.0.orig/utils/cryptoutils.c ++++ ibmtss-1.6.0/utils/cryptoutils.c +@@ -61,6 +61,9 @@ + #include + #include + #include ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++#include ++#endif + + #ifndef TPM_TSS_NOECC + #include +@@ -75,6 +78,9 @@ + #include + #include + ++TPM_RC TSS_Hash_GetMd(const EVP_MD **md, ++ TPMI_ALG_HASH hashAlg); ++ + #include "objecttemplates.h" + #include "cryptoutils.h" + +@@ -283,7 +289,8 @@ TPM_RC convertPemToEvpPubKey(EVP_PKEY ** + The return is void because the structure is opaque to the caller. This accomodates other crypto + libraries. + +- rsaKey is an RSA structure ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, + */ + + TPM_RC convertPemToRsaPrivKey(void **rsaKey, /* freed by caller */ +@@ -297,7 +304,11 @@ TPM_RC convertPemToRsaPrivKey(void **rsa + rc = TSS_File_Open(&pemKeyFile, pemKeyFilename, "rb"); /* closed @1 */ + } + if (rc == 0) { ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + *rsaKey = (void *)PEM_read_RSAPrivateKey(pemKeyFile, NULL, NULL, (void *)password); ++#else ++ *rsaKey = (void *)PEM_read_PrivateKey(pemKeyFile, NULL, NULL, (void *)password); ++#endif + if (*rsaKey == NULL) { + printf("convertPemToRsaPrivKey: Error in OpenSSL PEM_read_RSAPrivateKey()\n"); + rc = TSS_RC_PEM_ERROR; +@@ -334,6 +345,8 @@ TPM_RC convertEvpPkeyToEckey(EC_KEY **ec + #endif /* TPM_TSS_NOECC */ + #endif /* TPM_TPM20 */ + ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ + /* convertEvpPkeyToRsakey() retrieves the RSA key token from the EVP_PKEY */ + + TPM_RC convertEvpPkeyToRsakey(RSA **rsaKey, /* freed by caller */ +@@ -350,6 +363,7 @@ TPM_RC convertEvpPkeyToRsakey(RSA **rsaK + } + return rc; + } ++#endif + + #ifdef TPM_TPM20 + #ifndef TPM_TSS_NOECC +@@ -426,19 +440,26 @@ TPM_RC convertEcKeyToPrivateKeyBin(int + #endif /* TPM_TPM20 */ + + /* convertRsaKeyToPrivateKeyBin() converts an OpenSSL RSA key token private prime p to a binary +- array */ ++ array ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, ++*/ + + TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes, + uint8_t **privateKeyBin, /* freed by caller */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + const RSA *rsaKey) ++#else ++ const EVP_PKEY *rsaKey) ++#endif + { + TPM_RC rc = 0; + const BIGNUM *p = NULL; +- const BIGNUM *q; + + /* get the private primes */ + if (rc == 0) { +- rc = getRsaKeyParts(NULL, NULL, NULL, &p, &q, rsaKey); ++ rc = getRsaKeyParts(NULL, NULL, NULL, &p, NULL, rsaKey); /* freed @2 */ + } + /* allocate a buffer for the private key array */ + if (rc == 0) { +@@ -448,7 +469,10 @@ TPM_RC convertRsaKeyToPrivateKeyBin(int + /* convert the private key bignum to binary */ + if (rc == 0) { + BN_bn2bin(p, *privateKeyBin); +- } ++ } ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++ BN_free((BIGNUM *)p); /* @2 */ ++#endif + return rc; + } + +@@ -500,7 +524,11 @@ TPM_RC convertEcKeyToPublicKeyBin(int + #endif /* TPM_TSS_NOECC */ + #endif /* TPM_TPM20 */ + +-/* convertRsaKeyToPublicKeyBin() converts from an openssl RSA key token to a public modulus */ ++/* convertRsaKeyToPublicKeyBin() converts from an openssl RSA key token to a public modulus ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, ++*/ + + TPM_RC convertRsaKeyToPublicKeyBin(int *modulusBytes, + uint8_t **modulusBin, /* freed by caller */ +@@ -508,12 +536,10 @@ TPM_RC convertRsaKeyToPublicKeyBin(int + { + TPM_RC rc = 0; + const BIGNUM *n = NULL; +- const BIGNUM *e; +- const BIGNUM *d; + + /* get the public modulus from the RSA key token */ + if (rc == 0) { +- rc = getRsaKeyParts(&n, &e, &d, NULL, NULL, rsaKey); ++ rc = getRsaKeyParts(&n, NULL, NULL, NULL, NULL, rsaKey); + } + if (rc == 0) { + *modulusBytes = BN_num_bytes(n); +@@ -524,7 +550,10 @@ TPM_RC convertRsaKeyToPublicKeyBin(int + if (rc == 0) { + BN_bn2bin(n, *modulusBin); + } +- return rc; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++ BN_free((BIGNUM *)n); /* @2 */ ++#endif ++ return rc; + } + + #ifdef TPM_TPM20 +@@ -882,11 +911,18 @@ TPM_RC convertEcKeyToPrivate(TPM2B_PRIVA + + /* convertRsaKeyToPrivate() converts an openssl RSA key token to either a TPM2B_PRIVATE or + TPM2B_SENSITIVE ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, + */ + + TPM_RC convertRsaKeyToPrivate(TPM2B_PRIVATE *objectPrivate, + TPM2B_SENSITIVE *objectSensitive, +- RSA *rsaKey, ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ RSA *rsaKey, ++#else ++ EVP_PKEY *rsaKey, ++#endif + const char *password) + { + TPM_RC rc = 0; +@@ -957,7 +993,11 @@ TPM_RC convertEcKeyToPublic(TPM2B_PUBLIC + + #ifdef TPM_TPM20 + +-/* convertRsaKeyToPublic() converts from an openssl RSA key token to a TPM2B_PUBLIC */ ++/* convertRsaKeyToPublic() converts from an openssl RSA key token to a TPM2B_PUBLIC ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, ++*/ + + TPM_RC convertRsaKeyToPublic(TPM2B_PUBLIC *objectPublic, + int keyType, +@@ -1110,16 +1150,25 @@ TPM_RC convertRsaPemToKeyPair(TPM2B_PUBL + { + TPM_RC rc = 0; + EVP_PKEY *evpPkey = NULL; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA *rsaKey = NULL; +- ++#else ++ EVP_PKEY *rsaKey = NULL; ++#endif ++ + if (rc == 0) { + rc = convertPemToEvpPrivKey(&evpPkey, /* freed @1 */ + pemKeyFilename, + password); + } + if (rc == 0) { ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + rc = convertEvpPkeyToRsakey(&rsaKey, /* freed @2 */ + evpPkey); ++#else ++ /* openssl 3.0.0 and up use the EVP_PKEY directly */ ++ rsaKey = evpPkey; ++#endif + } + if (rc == 0) { + rc = convertRsaKeyToPrivate(objectPrivate, /* TPM2B_PRIVATE */ +@@ -1135,10 +1184,12 @@ TPM_RC convertRsaPemToKeyPair(TPM2B_PUBL + halg, + rsaKey); + } +- TSS_RsaFree(rsaKey); /* @2 */ + if (evpPkey != NULL) { + EVP_PKEY_free(evpPkey); /* @1 */ + } ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ TSS_RsaFree(rsaKey); /* @2 */ ++#endif + return rc; + } + +@@ -1281,7 +1332,11 @@ TPM_RC convertRsaDerToKeyPair(TPM2B_PUBL + const char *password) + { + TPM_RC rc = 0; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA *rsaKey = NULL; ++#else ++ EVP_PKEY *rsaKey = NULL; ++#endif + unsigned char *derBuffer = NULL; + size_t derSize; + +@@ -1293,7 +1348,12 @@ TPM_RC convertRsaDerToKeyPair(TPM2B_PUBL + } + if (rc == 0) { + const unsigned char *tmpPtr = derBuffer; /* because pointer moves */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + rsaKey = d2i_RSAPrivateKey(NULL, &tmpPtr, (long)derSize); /* freed @2 */ ++#else ++ rsaKey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, ++ &tmpPtr, (long)derSize); ++#endif + if (rsaKey == NULL) { + printf("convertRsaDerToKeyPair: could not convert key to RSA\n"); + rc = TPM_RC_VALUE; +@@ -1331,7 +1391,11 @@ TPM_RC convertRsaDerToPublic(TPM2B_PUBLI + const char *derKeyFilename) + { + TPM_RC rc = 0; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA *rsaKey = NULL; ++#else ++ EVP_PKEY *rsaKey = NULL; ++#endif + unsigned char *derBuffer = NULL; + size_t derSize; + +@@ -1343,7 +1407,11 @@ TPM_RC convertRsaDerToPublic(TPM2B_PUBLI + } + if (rc == 0) { + const unsigned char *tmpPtr = derBuffer; /* because pointer moves */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + rsaKey = d2i_RSA_PUBKEY(NULL, &tmpPtr, (long)derSize); /* freed @2 */ ++#else ++ rsaKey = d2i_PUBKEY(NULL, &tmpPtr, (long)derSize); ++#endif + if (rsaKey == NULL) { + printf("convertRsaDerToPublic: could not convert key to RSA\n"); + rc = TPM_RC_VALUE; +@@ -1362,13 +1430,6 @@ TPM_RC convertRsaDerToPublic(TPM2B_PUBLI + return rc; + } + +-#endif /* TPM_TSS_NORSA */ +-#endif /* TPM_TPM20 */ +-#endif /* TPM_TSS_NOFILE */ +- +-#ifndef TPM_TSS_NOFILE +-#ifdef TPM_TPM20 +- + /* convertRsaPemToPublic() converts an RSA public key in PEM format to a TPM2B_PUBLIC */ + + TPM_RC convertRsaPemToPublic(TPM2B_PUBLIC *objectPublic, +@@ -1380,15 +1441,24 @@ TPM_RC convertRsaPemToPublic(TPM2B_PUBLI + { + TPM_RC rc = 0; + EVP_PKEY *evpPkey = NULL; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA *rsaKey = NULL; ++#else ++ EVP_PKEY *rsaKey = NULL; ++#endif + + if (rc == 0) { + rc = convertPemToEvpPubKey(&evpPkey, /* freed @1 */ + pemKeyFilename); + } + if (rc == 0) { ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + rc = convertEvpPkeyToRsakey(&rsaKey, /* freed @2 */ + evpPkey); ++#else ++ /* openssl 3.0.0 and up use the EVP_PKEY directly */ ++ rsaKey = evpPkey; ++#endif + } + if (rc == 0) { + rc = convertRsaKeyToPublic(objectPublic, +@@ -1398,35 +1468,97 @@ TPM_RC convertRsaPemToPublic(TPM2B_PUBLI + halg, + rsaKey); + } +- RSA_free(rsaKey); /* @2 */ + if (evpPkey != NULL) { + EVP_PKEY_free(evpPkey); /* @1 */ + } ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ TSS_RsaFree(rsaKey); /* @2 */ ++#endif + return rc; + } + ++#endif /* TPM_TSS_NORSA */ + #endif /* TPM_TPM20 */ + #endif /* TPM_TSS_NOFILE */ + + /* getRsaKeyParts() gets the RSA key parts from an OpenSSL RSA key token. + + If n is not NULL, returns n, e, and d. If p is not NULL, returns p and q. ++ ++ For openssl < 3.0.0, the bignums are references to the RSA key and should not be freed separately. ++ ++ For openssl >= 3.0.0, the bignums are allocated and must be freed. ++ ++ FIXME - is there a better way? + */ + + TPM_RC getRsaKeyParts(const BIGNUM **n, +- const BIGNUM **e, +- const BIGNUM **d, +- const BIGNUM **p, +- const BIGNUM **q, +- const RSA *rsaKey) ++ const BIGNUM **e, ++ const BIGNUM **d, ++ const BIGNUM **p, ++ const BIGNUM **q, ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ const RSA *rsaKey) ++#else ++ const EVP_PKEY *rsaKey) ++#endif + { + TPM_RC rc = 0; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + if (n != NULL) { + RSA_get0_key(rsaKey, n, e, d); + } + if (p != NULL) { + RSA_get0_factors(rsaKey, p, q); + } ++#else ++ int irc; ++ if (rc == 0) { ++ if (n != NULL) { ++ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_N, (BIGNUM **)n); ++ if (irc != 1) { ++ printf("getRsaKeyParts: Error getting n\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ } ++ if (rc == 0) { ++ if (e != NULL) { ++ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_E, (BIGNUM **)e); ++ if (irc != 1) { ++ printf("getRsaKeyParts: Error getting e\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ } ++ if (rc == 0) { ++ if (d != NULL) { ++ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_D, (BIGNUM **)d); ++ if (irc != 1) { ++ printf("getRsaKeyParts: Error getting d\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ } ++ if (rc == 0) { ++ if (p != NULL) { ++ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_FACTOR1, (BIGNUM **)p); ++ if (irc != 1) { ++ printf("getRsaKeyParts: Error getting p\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ } ++ if (rc == 0) { ++ if (q != NULL) { ++ irc = EVP_PKEY_get_bn_param(rsaKey, OSSL_PKEY_PARAM_RSA_FACTOR2, (BIGNUM **)q); ++ if (irc != 1) { ++ printf("getRsaKeyParts: Error getting q\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ } ++#endif + return rc; + } + +@@ -1501,11 +1633,16 @@ TPM_RC convertRsaPublicToEvpPubKey(EVP_P + const TPM2B_PUBLIC_KEY_RSA *tpm2bRsa) + { + TPM_RC rc = 0; ++ /* public exponent */ ++ unsigned char earr[3] = {0x01, 0x00, 0x01}; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + int irc; + RSA *rsaPubKey = NULL; +- ++#endif ++ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + if (rc == 0) { +- *evpPubkey = EVP_PKEY_new(); ++ *evpPubkey = EVP_PKEY_new(); /* freed by caller */ + if (*evpPubkey == NULL) { + printf("convertRsaPublicToEvpPubKey: EVP_PKEY failed\n"); + rc = TSS_RC_OUT_OF_MEMORY; +@@ -1513,10 +1650,10 @@ TPM_RC convertRsaPublicToEvpPubKey(EVP_P + } + /* TPM to RSA token */ + if (rc == 0) { +- /* public exponent */ +- unsigned char earr[3] = {0x01, 0x00, 0x01}; ++ /* For Openssl < 3, rsaKey is an RSA structure. */ ++ /* For Openssl 3, rsaKey is an EVP_PKEY. */ + rc = TSS_RSAGeneratePublicTokenI +- ((void **)&rsaPubKey, /* freed as part of EVP_PKEY */ ++ ((void **)&rsaPubKey, /* freed by caller */ + tpm2bRsa->t.buffer, /* public modulus */ + tpm2bRsa->t.size, + earr, /* public exponent */ +@@ -1526,11 +1663,24 @@ TPM_RC convertRsaPublicToEvpPubKey(EVP_P + if (rc == 0) { + irc = EVP_PKEY_assign_RSA(*evpPubkey, rsaPubKey); + if (irc == 0) { +- TSS_RsaFree(rsaPubKey); /* because not assigned tp EVP_PKEY */ ++ TSS_RsaFree(rsaPubKey); /* because not assigned to EVP_PKEY */ + printf("convertRsaPublicToEvpPubKey: EVP_PKEY_assign_RSA failed\n"); + rc = TSS_RC_RSA_KEY_CONVERT; + } + } ++#else /* FIXME this should always work? */ ++ /* TPM to RSA token */ ++ if (rc == 0) { ++ /* For Openssl < 3, rsaKey is an RSA structure. */ ++ /* For Openssl 3, rsaKey is an EVP_PKEY. */ ++ rc = TSS_RSAGeneratePublicTokenI ++ ((void **)evpPubkey, /* freed by caller */ ++ tpm2bRsa->t.buffer, /* public modulus */ ++ tpm2bRsa->t.size, ++ earr, /* public exponent */ ++ sizeof(earr)); ++ } ++#endif + return rc; + } + +@@ -1828,8 +1978,9 @@ TPM_RC verifyRSASignatureFromEvpPubKey(u + EVP_PKEY *evpPkey) + { + TPM_RC rc = 0; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA *rsaPubKey = NULL; /* OpenSSL public key, RSA format */ +- ++ + /* construct the RSA key token */ + if (rc == 0) { + rsaPubKey = EVP_PKEY_get1_RSA(evpPkey); /* freed @1 */ +@@ -1838,6 +1989,9 @@ TPM_RC verifyRSASignatureFromEvpPubKey(u + rc = TSS_RC_RSA_KEY_CONVERT; + } + } ++#else ++ EVP_PKEY *rsaPubKey = evpPkey; ++#endif + if (rc == 0) { + rc = verifyRSASignatureFromRSA(message, + messageSize, +@@ -1845,11 +1999,17 @@ TPM_RC verifyRSASignatureFromEvpPubKey(u + halg, + rsaPubKey); + } ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + TSS_RsaFree(rsaPubKey); /* @1 */ ++#endif + return rc; + } + +-/* signRSAFromRSA() signs digest to signature, using th4 RSA key rsaKey. */ ++/* signRSAFromRSA() signs digest to signature, using rsaKey. ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, ++*/ + + TPM_RC signRSAFromRSA(uint8_t *signature, size_t *signatureLength, + size_t signatureSize, +@@ -1859,8 +2019,9 @@ TPM_RC signRSAFromRSA(uint8_t *signature + { + TPM_RC rc = 0; + int irc; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + int nid; /* openssl hash algorithm */ +- ++ + /* map the hash algorithm to the openssl NID */ + if (rc == 0) { + switch (hashAlg) { +@@ -1903,6 +2064,54 @@ TPM_RC signRSAFromRSA(uint8_t *signature + rc = TSS_RC_RSA_SIGNATURE; + } + } ++#else ++ EVP_PKEY_CTX *ctx = NULL; ++ const EVP_MD *md; ++ ++ if (rc == 0) { ++ ctx = EVP_PKEY_CTX_new(rsaKey, NULL); /* freed @1 */ ++ if (ctx == NULL) { ++ printf("signRSAFromRSA: Error in EVP_PKEY_CTX_new()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_sign_init(ctx); ++ if (irc != 1) { ++ printf("signRSAFromRSA: Error in EVP_PKEY_sign_init()\n"); ++ rc = TSS_RC_RSA_SIGNATURE; ++ } ++ } ++ if (rc == 0) { ++ rc = TSS_Hash_GetMd(&md, hashAlg); ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_CTX_set_signature_md(ctx, md); ++ if (irc <= 0) { ++ printf("signRSAFromRSA: Error in EVP_PKEY_CTX_set_signature_md()\n"); ++ rc = TSS_RC_RSA_SIGNATURE; ++ } ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING); ++ if (irc <= 0) { ++ printf("signRSAFromRSA: Error in EVP_PKEY_CTX_set_rsa_padding()\n"); ++ rc = TSS_RC_RSA_SIGNATURE; ++ } ++ } ++ if (rc == 0) { ++ size_t siglen = signatureSize; ++ irc = EVP_PKEY_sign(ctx, ++ signature, &siglen, ++ digest, (unsigned int)digestLength); ++ *signatureLength = siglen; ++ if (irc != 1) { ++ printf("signRSAFromRSA: Error in EVP_PKEY_sign()\n"); ++ rc = TSS_RC_RSA_SIGNATURE; ++ } ++ } ++ EVP_PKEY_CTX_free(ctx); /* @1 */ ++#endif + return rc; + } + +@@ -1910,6 +2119,9 @@ TPM_RC signRSAFromRSA(uint8_t *signature + using the RSA public key in the OpenSSL RSA format. + + Supports RSASSA and RSAPSS schemes. ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, + */ + + TPM_RC verifyRSASignatureFromRSA(unsigned char *message, +@@ -1920,9 +2132,10 @@ TPM_RC verifyRSASignatureFromRSA(unsigne + { + TPM_RC rc = 0; + int irc; ++ const EVP_MD *md = NULL; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + int nid = 0; /* initialized these two to suppress false gcc -O3 + warnings */ +- const EVP_MD *md = NULL; + /* map from hash algorithm to openssl nid */ + if (rc == 0) { + switch (halg) { +@@ -1989,8 +2202,68 @@ TPM_RC verifyRSASignatureFromRSA(unsigne + else { + printf("verifyRSASignatureFromRSA: Bad signature scheme %04x\n", + tSignature->sigAlg); ++ rc = TSS_RC_RSA_SIGNATURE; + } +- return rc; ++#else ++ EVP_PKEY_CTX *ctx = NULL; ++ ++ if (rc == 0) { ++ ctx = EVP_PKEY_CTX_new(rsaPubKey, NULL); /* freed @1 */ ++ if (ctx == NULL) { ++ printf("verifyRSAFSignatureromRSA: Error in EVP_PKEY_CTX_new()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_verify_init(ctx); ++ if (irc != 1) { ++ printf("verifyRSASignatureFromRSA: Error in EVP_PKEY_verify_init()\n"); ++ rc = TSS_RC_RSA_SIGNATURE; ++ } ++ } ++ if (rc == 0) { ++ rc = TSS_Hash_GetMd(&md, halg); ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_CTX_set_signature_md(ctx, md); ++ if (irc <= 0) { ++ printf("verifyRSASignatureFromRSA: Error in EVP_PKEY_CTX_set_signature_md()\n"); ++ rc = TSS_RC_RSA_SIGNATURE; ++ } ++ } ++ /* verify the signature */ ++ if (rc == 0) { ++ if (tSignature->sigAlg == TPM_ALG_RSASSA) { ++ irc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING); ++ } ++ else if (tSignature->sigAlg == TPM_ALG_RSAPSS) { ++ irc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING); ++ } ++ else { ++ rc = TSS_RC_RSA_SIGNATURE; ++ printf("verifyRSASignatureFromRSA: Bad signature scheme %04x\n", ++ tSignature->sigAlg); ++ } ++ } ++ if (rc == 0) { ++ if (irc <= 0) { ++ printf("verifyRSASignatureFromRSA: Error in EVP_PKEY_CTX_set_rsa_padding()\n"); ++ rc = TSS_RC_RSA_SIGNATURE; ++ } ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_verify(ctx, ++ tSignature->signature.rsapss.sig.t.buffer, ++ tSignature->signature.rsapss.sig.t.size, ++ message, messageSize); ++ if (irc != 1) { ++ printf("verifyRSASignatureFromRSA: Error in EVP_PKEY_verify()\n"); ++ rc = TSS_RC_RSA_SIGNATURE; ++ } ++ } ++ EVP_PKEY_CTX_free(ctx); /* @1 */ ++#endif ++ return rc; + } + + #endif /* TPM_TSS_NORSA */ +Index: ibmtss-1.6.0/utils/cryptoutils.h +=================================================================== +--- ibmtss-1.6.0.orig/utils/cryptoutils.h ++++ ibmtss-1.6.0/utils/cryptoutils.h +@@ -248,9 +248,10 @@ extern "C" { + + TPM_RC convertEvpPkeyToRsakey(RSA **rsaKey, + EVP_PKEY *evpPkey); +- TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes, ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes, + uint8_t **privateKeyBin, +- const RSA *rsaKey); ++ const RSA *rsaKey); + TPM_RC convertRsaKeyToPrivate(TPM2B_PRIVATE *objectPrivate, + TPM2B_SENSITIVE *objectSensitive, + RSA *rsaKey, +@@ -260,7 +261,22 @@ extern "C" { + const BIGNUM **d, + const BIGNUM **p, + const BIGNUM **q, +- const RSA *rsaKey); ++ const RSA *rsaKey); ++#else ++ TPM_RC convertRsaKeyToPrivateKeyBin(int *privateKeyBytes, ++ uint8_t **privateKeyBin, ++ const EVP_PKEY *rsaKey); ++ TPM_RC convertRsaKeyToPrivate(TPM2B_PRIVATE *objectPrivate, ++ TPM2B_SENSITIVE *objectSensitive, ++ EVP_PKEY *rsaKey, ++ const char *password); ++ TPM_RC getRsaKeyParts(const BIGNUM **n, ++ const BIGNUM **e, ++ const BIGNUM **d, ++ const BIGNUM **p, ++ const BIGNUM **q, ++ const EVP_PKEY *rsaKey); ++#endif + int getRsaPubkeyAlgorithm(EVP_PKEY *pkey); + TPM_RC convertRsaPublicToEvpPubKey(EVP_PKEY **evpPubkey, + const TPM2B_PUBLIC_KEY_RSA *tpm2bRsa); +Index: ibmtss-1.6.0/utils/efilib.c +=================================================================== +--- ibmtss-1.6.0.orig/utils/efilib.c ++++ ibmtss-1.6.0/utils/efilib.c +@@ -64,6 +64,7 @@ + #include + #include + #include ++#include + + #include "eventlib.h" + #include "efilib.h" +@@ -4802,7 +4803,13 @@ static void TSS_EfiEventTag_Trace(TS + uint32_t count; + TSS_UEFI_TAGGED_EVENT *taggedEventList = &efiData->efiData.taggedEventList; + #ifndef TPM_TSS_MBEDTLS +- RSA *rsaKey = NULL; ++#ifndef TPM_TSS_NORSA ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ RSA *rsaKey = NULL; ++#else ++ EVP_PKEY *rsaKey = NULL; ++#endif ++#endif /* TPM_TSS_NORSA */ + #endif /* TPM_TSS_MBEDTLS */ + + printf(" tagged events %u\n", taggedEventList->count); +@@ -4812,17 +4819,25 @@ static void TSS_EfiEventTag_Trace(TS + printf(" taggedEventID %08x\n", taggedEvent->taggedEventID); + /* https://github.com/mattifestation/TCGLogTools/blob/master/TCGLogTools.psm1 */ + /* by observation 0x00060002 appears to be a DER encoded public key */ +-#ifndef TPM_TSS_MBEDTLS ++#if ! defined TPM_TSS_MBEDTLS && ! defined TPM_TSS_NORSA + if (taggedEvent->taggedEventID == 0x00060002) { + const unsigned char *tmpData = NULL; + /* tmp pointer because d2i moves the pointer */ + tmpData = taggedEvent->taggedEventData; +- rsaKey = d2i_RSA_PUBKEY(NULL, &tmpData , taggedEvent->taggedEventDataSize); /* freed @2 */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ rsaKey = d2i_RSA_PUBKEY(NULL, &tmpData ,taggedEvent->taggedEventDataSize); /* freed @2 */ ++#else ++ rsaKey = d2i_PUBKEY(NULL, &tmpData, (long)taggedEvent->taggedEventDataSize); ++#endif /* OPENSSL_VERSION_NUMBER */ + if (rsaKey != NULL) { /* success */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA_print_fp(stdout, rsaKey, 4); ++#else ++ EVP_PKEY_print_public_fp(stdout, rsaKey, 4, NULL); ++#endif /* OPENSSL_VERSION_NUMBER */ + } + if (rsaKey != NULL) { +- RSA_free(rsaKey); ++ TSS_RsaFree(rsaKey); /* @2 */ + } + } + /* if it's not 0x00060002 or if the d2i fails */ +@@ -4831,10 +4846,10 @@ static void TSS_EfiEventTag_Trace(TS + TSS_PrintAll(" taggedEvent", + taggedEvent->taggedEventData, taggedEvent->taggedEventDataSize); + } +-#else ++#else /* TPM_TSS_MBEDTLS or TPM_TSS_NORSA */ + TSS_PrintAll(" taggedEvent", + taggedEvent->taggedEventData, taggedEvent->taggedEventDataSize); +-#endif /* TPM_TSS_MBEDTLS */ ++#endif /* TPM_TSS_MBEDTLS TPM_TSS_NORSA */ + } + return; + } +Index: ibmtss-1.6.0/utils/ekutils.c +=================================================================== +--- ibmtss-1.6.0.orig/utils/ekutils.c ++++ ibmtss-1.6.0/utils/ekutils.c +@@ -567,9 +567,12 @@ TPM_RC getIndexX509Certificate(TSS_CONTE + certificate stored in a file. + + Returns both the OpenSSL X509 certificate token and RSA public key token. ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, + */ + +-uint32_t getPubkeyFromDerCertFile(RSA **rsaPkey, ++uint32_t getPubkeyFromDerCertFile(void **rsaPkey, /* freed by caller */ + X509 **x509, + const char *derCertificateFileName) + { +@@ -594,7 +597,7 @@ uint32_t getPubkeyFromDerCertFile(RSA * + } + /* extract the OpenSSL format public key from the X509 token */ + if (rc == 0) { +- rc = getPubKeyFromX509Cert(rsaPkey, *x509); ++ rc = getPubKeyFromX509Cert(rsaPkey, *x509); /* freed by caller */ + } + /* for debug, print the X509 certificate */ + if (rc == 0) { +@@ -612,9 +615,13 @@ uint32_t getPubkeyFromDerCertFile(RSA * + #ifndef TPM_TSS_NORSA + + /* getPubKeyFromX509Cert() gets an OpenSSL RSA public key token from an OpenSSL X509 certificate +- token. */ ++ token. ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, ++*/ + +-uint32_t getPubKeyFromX509Cert(RSA **rsaPkey, ++uint32_t getPubKeyFromX509Cert(void **rsaPkey, + X509 *x509) + { + uint32_t rc = 0; +@@ -623,20 +630,24 @@ uint32_t getPubKeyFromX509Cert(RSA **rs + if (rc == 0) { + evpPkey = X509_get_pubkey(x509); /* freed @1 */ + if (evpPkey == NULL) { +- printf("getPubKeyFromX509Cert: X509_get_pubkey failed\n"); ++ printf("getPubKeyFromX509Cert: X509_get_pubkey failed\n"); + rc = TSS_RC_X509_ERROR; + } + } ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + if (rc == 0) { + *rsaPkey = EVP_PKEY_get1_RSA(evpPkey); + if (*rsaPkey == NULL) { +- printf("getPubKeyFromX509Cert: EVP_PKEY_get1_RSA failed\n"); ++ printf("getPubKeyFromX509Cert: EVP_PKEY_get1_RSA failed\n"); + rc = TSS_RC_X509_ERROR; + } + } + if (evpPkey != NULL) { + EVP_PKEY_free(evpPkey); /* @1 */ + } ++#else ++ *rsaPkey = evpPkey; ++#endif + return rc; + } + #endif /* TPM_TSS_NORSA */ +@@ -1105,8 +1116,8 @@ TPM_RC convertX509ToEc(EC_KEY **ecKey, / + + If print is true, prints the EK certificate + +- The return is void because the structure is opaque to the caller. This accomodates other crypto +- libraries. ++ The ekCertificate return is void because the structure is opaque to the caller. This ++ accommodates other crypto libraries. + + ekCertificate is an X509 structure. + */ +@@ -1158,7 +1169,11 @@ TPM_RC convertCertificatePubKey(uint8_t + case EK_CERT_RSA_3072_INDEX_H6: + case EK_CERT_RSA_4096_INDEX_H7: + { ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA *rsaKey = NULL; ++#else ++ EVP_PKEY *rsaKey = NULL; ++#endif + /* check that the public key algorithm matches the ekCertIndex algorithm */ + if (rc == 0) { + if (pkeyType != EVP_PKEY_RSA) { +@@ -1169,12 +1184,16 @@ TPM_RC convertCertificatePubKey(uint8_t + } + /* convert the public key to OpenSSL structure */ + if (rc == 0) { ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + rsaKey = EVP_PKEY_get1_RSA(pkey); /* freed @3 */ + if (rsaKey == NULL) { + printf("convertCertificatePubKey: Could not extract RSA public key " + "from X509 certificate\n"); + rc = TPM_RC_INTEGRITY; + } ++#else /* use the EVP_PKEY directly */ ++ rsaKey = pkey; ++#endif + } + if (rc == 0) { + rc = convertRsaKeyToPublicKeyBin(modulusBytes, +@@ -1185,7 +1204,9 @@ TPM_RC convertCertificatePubKey(uint8_t + if (print) TSS_PrintAll("Certificate public key:", + *modulusBin, *modulusBytes); + } ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA_free(rsaKey); /* @3 */ ++#endif + } + break; + #endif /* TPM_TSS_NORSA */ +@@ -1254,7 +1275,11 @@ TPM_RC convertCertificatePubKey12(uint8_ + const unsigned char *pk = NULL; /* do not free */ + int ppklen; + X509_ALGOR *palg = NULL; /* algorithm identifier for public key */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA *rsaKey = NULL; ++#else ++ EVP_PKEY *rsaKey = NULL; ++#endif + + /* get internal pointer to the public key in the certificate */ + if (rc == 0) { +@@ -1278,7 +1303,12 @@ TPM_RC convertCertificatePubKey12(uint8_ + } + if (rc == 0) { + const unsigned char *tmppk = pk; /* because d2i moves the pointer */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + rsaKey = d2i_RSAPublicKey(NULL, &tmppk, ppklen); /* freed @1 */ ++#else ++ rsaKey = d2i_PublicKey(EVP_PKEY_RSA, NULL, ++ &tmppk, (long)ppklen); ++#endif + if (rsaKey == NULL) { + printf("convertCertificatePubKey12: Could not convert to RSA structure\n"); + rc = TPM_RC_INTEGRITY; +@@ -1290,9 +1320,7 @@ TPM_RC convertCertificatePubKey12(uint8_ + rsaKey); + TSS_PrintAll("convertCertificatePubKey12", *modulusBin, *modulusBytes); + } +- if (rsaKey != NULL) { +- RSA_free(rsaKey); /* @1 */ +- } ++ TSS_RsaFree(rsaKey); /* @1 */ + return rc; + } + +Index: ibmtss-1.6.0/utils/ekutils.h +=================================================================== +--- ibmtss-1.6.0.orig/utils/ekutils.h ++++ ibmtss-1.6.0/utils/ekutils.h +@@ -218,10 +218,10 @@ extern "C" { + #ifndef TPM_TSS_NO_OPENSSL + + +- uint32_t getPubkeyFromDerCertFile(RSA **rsaPkey, ++ uint32_t getPubkeyFromDerCertFile(void **rsaPkey, + X509 **x509, + const char *derCertificateFileName); +- uint32_t getPubKeyFromX509Cert(RSA **rsaPkey, ++ uint32_t getPubKeyFromX509Cert(void **rsaPkey, + X509 *x509); + TPM_RC getCaStore(X509_STORE **caStore, + X509 *caCert[], +Index: ibmtss-1.6.0/utils/ibmtss/tsscrypto.h +=================================================================== +--- ibmtss-1.6.0.orig/utils/ibmtss/tsscrypto.h ++++ ibmtss-1.6.0/utils/ibmtss/tsscrypto.h +@@ -4,7 +4,7 @@ + /* Written by Ken Goldman */ + /* IBM Thomas J. Watson Research Center */ + /* */ +-/* (c) Copyright IBM Corporation 2015 - 2019. */ ++/* (c) Copyright IBM Corporation 2015 - 2021. */ + /* */ + /* All rights reserved. */ + /* */ +@@ -107,6 +107,7 @@ extern "C" { + LIB_EXPORT + TPM_RC TSS_RsaNew(void **rsaKey); + ++ /* deprecated */ + LIB_EXPORT + TPM_RC TSS_RSAGeneratePublicToken(RSA **rsa_pub_key, /* freed by caller */ + const unsigned char *narr, /* public modulus */ +Index: ibmtss-1.6.0/utils/sign.c +=================================================================== +--- ibmtss-1.6.0.orig/utils/sign.c ++++ ibmtss-1.6.0/utils/sign.c +@@ -4,7 +4,7 @@ + /* Written by Ken Goldman */ + /* IBM Thomas J. Watson Research Center */ + /* */ +-/* (c) Copyright IBM Corporation 2015 - 2019. */ ++/* (c) Copyright IBM Corporation 2015 - 2021. */ + /* */ + /* All rights reserved. */ + /* */ +@@ -426,6 +426,8 @@ int main(int argc, char *argv[]) + /* construct the OpenSSL RSA public key token */ + if (rc == 0) { + unsigned char earr[3] = {0x01, 0x00, 0x01}; ++ /* For Openssl < 3, rsaKey is an RSA structure. */ ++ /* For Openssl 3, rsaKey is an EVP_PKEY. */ + rc = TSS_RSAGeneratePublicTokenI + (&rsaPubKey, /* freed @2 */ + public.publicArea.unique.rsa.t.buffer, /* public modulus */ +Index: ibmtss-1.6.0/utils/tsscrypto.c +=================================================================== +--- ibmtss-1.6.0.orig/utils/tsscrypto.c ++++ ibmtss-1.6.0/utils/tsscrypto.c +@@ -5,7 +5,7 @@ + /* IBM Thomas J. Watson Research Center */ + /* ECC Salt functions written by Bill Martin */ + /* */ +-/* (c) Copyright IBM Corporation 2015 - 2019. */ ++/* (c) Copyright IBM Corporation 2015 - 2021. */ + /* */ + /* All rights reserved. */ + /* */ +@@ -37,7 +37,7 @@ + /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /********************************************************************************/ + +-/* Interface to OpenSSL version 1.0 or 1.1 crypto library */ ++/* Interface to OpenSSL version 1.0.2, 1.1.1, 3.0.0 crypto library */ + + #include + #include +@@ -59,6 +59,10 @@ + #include + #include + ++#if OPENSSL_VERSION_NUMBER >= 0x30000000 ++#include ++#endif ++ + #include + #include + #include +@@ -67,6 +71,9 @@ + #include + #include + ++TPM_RC TSS_Hash_GetMd(const EVP_MD **md, ++ TPMI_ALG_HASH hashAlg); ++ + extern int tssVverbose; + extern int tssVerbose; + +@@ -80,8 +87,6 @@ extern int tssVerbose; + /* local prototypes */ + + static TPM_RC TSS_Hash_GetOsslString(const char **str, TPMI_ALG_HASH hashAlg); +-static TPM_RC TSS_Hash_GetMd(const EVP_MD **md, +- TPMI_ALG_HASH hashAlg); + + #ifndef TPM_TSS_NOECC + +@@ -164,8 +169,8 @@ static TPM_RC TSS_Hash_GetOsslString(con + return rc; + } + +-static TPM_RC TSS_Hash_GetMd(const EVP_MD **md, +- TPMI_ALG_HASH hashAlg) ++TPM_RC TSS_Hash_GetMd(const EVP_MD **md, ++ TPMI_ALG_HASH hashAlg) + { + TPM_RC rc = 0; + const char *str = NULL; +@@ -220,14 +225,14 @@ TPM_RC TSS_HMAC_Generate_valist(TPMT_HA + } + #else + if (rc == 0) { +- mac = EVP_MAC_fetch(NULL, "hmac", NULL); ++ mac = EVP_MAC_fetch(NULL, "hmac", NULL); /* freed @2 */ + if (mac == NULL) { + if (tssVerbose) printf("TSS_Hash_Generate_valist: EVP_MAC_new failed\n"); + rc = TSS_RC_OUT_OF_MEMORY; + } + } + if (rc == 0) { +- ctx = EVP_MAC_CTX_new(mac); ++ ctx = EVP_MAC_CTX_new(mac); /* freed @1 */ + if (ctx == NULL) { + if (tssVerbose) printf("TSS_Hash_Generate_valist: EVP_MAC_CTX_new failed\n"); + rc = TSS_RC_OUT_OF_MEMORY; +@@ -298,7 +303,6 @@ TPM_RC TSS_HMAC_Generate_valist(TPMT_HA + done = TRUE; + } + } +- + if (rc == 0) { + #if OPENSSL_VERSION_NUMBER < 0x10100000 + irc = HMAC_Final(&ctx, (uint8_t *)&digest->digest, NULL); +@@ -317,9 +321,9 @@ TPM_RC TSS_HMAC_Generate_valist(TPMT_HA + #elif OPENSSL_VERSION_NUMBER < 0x30000000 + HMAC_CTX_free(ctx); + #else +- EVP_MAC_CTX_free(ctx); +- EVP_MAC_free(mac); +- #endif ++ EVP_MAC_CTX_free(ctx); /* @1 */ ++ EVP_MAC_free(mac); /* @2 */ ++#endif + return rc; + } + +@@ -407,7 +411,8 @@ TPM_RC TSS_RandBytes(unsigned char *buff + + This abstracts the crypto library specific allocation. + +- For Openssl, rsaKey is an RSA structure. ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, + */ + + TPM_RC TSS_RsaNew(void **rsaKey) +@@ -424,6 +429,7 @@ TPM_RC TSS_RsaNew(void **rsaKey) + } + } + /* construct the OpenSSL private key object */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + if (rc == 0) { + *rsaKey = RSA_new(); /* freed by caller */ + if (*rsaKey == NULL) { +@@ -431,20 +437,36 @@ TPM_RC TSS_RsaNew(void **rsaKey) + rc = TSS_RC_RSA_KEY_CONVERT; + } + } ++#else ++ if (rc == 0) { ++ *rsaKey = EVP_PKEY_new(); ++ if (*rsaKey == NULL) { ++ if (tssVerbose) printf("TSS_RsaNew: Error in EVP_PKEY_new()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ } ++#endif + return rc; + } + + /* TSS_RsaFree() frees an openssl RSA key token. + + This abstracts the crypto library specific free. +- +- For Openssl, rsaKey is an RSA structure. ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY, + */ + + void TSS_RsaFree(void *rsaKey) + { + if (rsaKey != NULL) { ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA_free(rsaKey); ++#else ++ EVP_PKEY_free(rsaKey); ++#endif + } + return; + } +@@ -473,42 +495,122 @@ TPM_RC TSS_RSAGeneratePublicToken(RSA ** + /* TSS_RSAGeneratePublicTokenI() generates an RSA key token from n and e + + Free rsa_pub_key using TSS_RsaFree(); ++ ++ For Openssl < 3, rsaKey is an RSA structure. ++ For Openssl 3, rsaKey is an EVP_PKEY. + */ + + TPM_RC TSS_RSAGeneratePublicTokenI(void **rsa_pub_key, /* freed by caller */ +- const unsigned char *narr, /* public modulus */ ++ const unsigned char *narr, /* public modulus */ + uint32_t nbytes, +- const unsigned char *earr, /* public exponent */ ++ const unsigned char *earr, /* public exponent */ + uint32_t ebytes) + { + TPM_RC rc = 0; ++#if OPENSSL_VERSION_NUMBER >= 0x10100000 ++ int irc; ++#endif + BIGNUM * n = NULL; + BIGNUM * e = NULL; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA ** rsaPubKey = (RSA **)rsa_pub_key; /* openssl specific structure */ ++#else ++ EVP_PKEY_CTX *ctx = NULL; ++ OSSL_PARAM_BLD *param_bld = NULL; ++ OSSL_PARAM *params = NULL; ++#endif + + /* construct the OpenSSL private key object */ ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + if (rc == 0) { +- rc = TSS_RsaNew(rsa_pub_key); +- } +- if (rc == 0) { +- rc = TSS_bin2bn(&n, narr, nbytes); /* freed by caller */ ++ rc = TSS_RsaNew(rsa_pub_key); /* freed by caller */ + } ++#endif + if (rc == 0) { +- rc = TSS_bin2bn(&e, earr, ebytes); /* freed by caller */ +- } ++ rc = TSS_bin2bn(&n, narr, nbytes); /* freed by caller, < 3.0.0 */ ++ } /* freed @4, 3.0.0 */ + if (rc == 0) { ++ rc = TSS_bin2bn(&e, earr, ebytes); /* freed by caller, < 3.0.0 */ ++ } /* freed @5, 3.0.0 */ + #if OPENSSL_VERSION_NUMBER < 0x10100000 ++ if (rc == 0) { + (*rsaPubKey)->n = n; + (*rsaPubKey)->e = e; + (*rsaPubKey)->d = NULL; +-#else +- int irc = RSA_set0_key(*rsaPubKey, n, e, NULL); ++ } ++#elif OPENSSL_VERSION_NUMBER < 0x30000000 ++ if (rc == 0) { ++ irc = RSA_set0_key(*rsaPubKey, n, e, NULL); + if (irc != 1) { + if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: Error in RSA_set0_key()\n"); + rc = TSS_RC_RSA_KEY_CONVERT; + } +-#endif + } ++#else ++ if (rc == 0) { ++ param_bld = OSSL_PARAM_BLD_new(); /* freed @2 */ ++ if (param_bld == NULL) { ++ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: Error in OSSL_PARAM_BLD_new()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ irc = OSSL_PARAM_BLD_push_BN(param_bld, "n", n); ++ if (irc != 1) { ++ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: " ++ "Error in OSSL_PARAM_BLD_push_BN()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ irc = OSSL_PARAM_BLD_push_BN(param_bld, "e", e); ++ if (irc != 1) { ++ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: " ++ "Error in OSSL_PARAM_BLD_push_BN()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ params = OSSL_PARAM_BLD_to_param(param_bld); /* freed @3 */ ++ if (params == NULL) { ++ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: " ++ "Error in OSSL_PARAM_BLD_to_param()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); /* freed @1 */ ++ if (ctx == NULL) { ++ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: " ++ "Error in EVP_PKEY_CTX_new_from_name()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_fromdata_init(ctx); ++ if (irc != 1) { ++ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: " ++ "Error in EVP_PKEY_fromdata_init()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_fromdata(ctx, (EVP_PKEY **)rsa_pub_key, /* freed by caller */ ++ EVP_PKEY_PUBLIC_KEY, params); ++ if (irc != 1) { ++ if (tssVerbose) printf("TSS_RSAGeneratePublicTokenI: " ++ "Error in OSSL_PARAM_BLD_push_BN()\n"); ++ rc = TSS_RC_RSA_KEY_CONVERT; ++ } ++ } ++ OSSL_PARAM_free(params); /* @3 */ ++ OSSL_PARAM_BLD_free(param_bld); /* @2 */ ++ EVP_PKEY_CTX_free(ctx); /* @1 */ ++ /* for openssl < 3.0.0, n and e are part of the RSA structure, freed with it. For 3.0.0 and up, ++ they're copied to the EVP_PKEY, so the parts are freed here. */ ++ BN_free(n); /* @4 */ ++ BN_free(e); /* @5 */ ++#endif + return rc; + } + +@@ -530,7 +632,12 @@ TPM_RC TSS_RSAPublicEncrypt(unsigned cha + { + TPM_RC rc = 0; + int irc; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 + RSA *rsa_pub_key = NULL; ++#else ++ EVP_PKEY *rsa_pub_key = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++#endif + unsigned char *padded_data = NULL; + + if (tssVverbose) printf(" TSS_RSAPublicEncrypt: Input data size %lu\n", +@@ -541,12 +648,16 @@ TPM_RC TSS_RSAPublicEncrypt(unsigned cha + } + /* construct the OpenSSL public key object */ + if (rc == 0) { +- rc = TSS_RSAGeneratePublicTokenI((void **)&rsa_pub_key, /* freed @1 */ ++ /* For Openssl < 3, rsaKey is an RSA structure. */ ++ /* For Openssl 3, rsaKey is an EVP_PKEY, */ ++ rc = TSS_RSAGeneratePublicTokenI((void **)&rsa_pub_key, /* freed @3 */ + narr, /* public modulus */ + nbytes, + earr, /* public exponent */ + ebytes); + } ++ /* Must pad first and then encrypt because the encrypt call cannot specify an encoding ++ parameter */ + if (rc == 0) { + padded_data[0] = 0x00; + rc = TSS_RSA_padding_add_PKCS1_OAEP(padded_data, /* to */ +@@ -563,25 +674,61 @@ TPM_RC TSS_RSAPublicEncrypt(unsigned cha + (unsigned long)encrypt_data_size); + if (tssVverbose) TSS_PrintAll(" TPM_RSAPublicEncrypt: Padded data", padded_data, + (uint32_t)encrypt_data_size); +- /* encrypt with public key. Must pad first and then encrypt because the encrypt +- call cannot specify an encoding parameter */ ++ } ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++ if (rc == 0) { ++ /* encrypt with public key. */ + /* returns the size of the encrypted data. On error, -1 is returned */ + irc = RSA_public_encrypt((int)encrypt_data_size, /* from length */ + padded_data, /* from - the clear text data */ + encrypt_data, /* the padded and encrypted data */ +- rsa_pub_key, /* key */ ++ rsa_pub_key, /* RSA key structure */ + RSA_NO_PADDING); /* padding */ + if (irc < 0) { + if (tssVerbose) printf("TSS_RSAPublicEncrypt: Error in RSA_public_encrypt()\n"); + rc = TSS_RC_RSA_ENCRYPT; + } + } ++#else ++ /* create EVP_PKEY_CTX for the encrypt */ ++ if (rc == 0) { ++ ctx = EVP_PKEY_CTX_new(rsa_pub_key, NULL); /* freed @1 */ ++ if (ctx == NULL) { ++ printf("TSS_RSAPublicEncrypt: Error in EVP_PKEY_CTX_new()\n"); ++ rc = TSS_RC_RSA_ENCRYPT; ++ } ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_encrypt_init(ctx); ++ if (irc != 1) { ++ printf("TSS_RSAPublicEncrypt: Error in EVP_PKEY_encrypt_init()\n"); ++ rc = TSS_RC_RSA_ENCRYPT; ++ } ++ } ++ if (rc == 0) { ++ irc = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING); ++ if (irc <= 0) { ++ if (tssVerbose) printf("TSS_RSAPublicEncrypt: Error in EVP_PKEY_CTX_set_rsa_padding\n"); ++ rc = TSS_RC_RSA_ENCRYPT; ++ } ++ } ++ if (rc == 0) { ++ size_t outlen = encrypt_data_size; ++ irc = EVP_PKEY_encrypt(ctx, ++ encrypt_data, &outlen, ++ padded_data, encrypt_data_size); ++ } ++#endif + if (rc == 0) { + if (tssVverbose) printf(" TSS_RSAPublicEncrypt: RSA_public_encrypt() success\n"); + } +- TSS_RsaFree(rsa_pub_key); /* @1 */ +- free(padded_data); /* @2 */ +- return rc; ++#if OPENSSL_VERSION_NUMBER < 0x30000000 ++#else ++ EVP_PKEY_CTX_free(ctx); /* @1 */ ++#endif ++ TSS_RsaFree(rsa_pub_key); /* @3 */ ++ free(padded_data); /* @2 */ ++ return rc; + } + + #endif /* TPM_TSS_NORSA */ diff --git a/ibmtss-utils-Remove-unused-variables-from-certifyx509.patch b/ibmtss-utils-Remove-unused-variables-from-certifyx509.patch new file mode 100644 index 0000000..6de75c0 --- /dev/null +++ b/ibmtss-utils-Remove-unused-variables-from-certifyx509.patch @@ -0,0 +1,51 @@ +From f335860d99fe11eec5599e1e53960ff1e75c0f82 Mon Sep 17 00:00:00 2001 +From: Ken Goldman +Date: Mon, 23 Aug 2021 17:30:56 -0400 +Subject: utils: Remove unused variables from certifyx509 + +notBefore and notAfter are set driectly in the partialCertificate +structure, and that is used to directly set the x509 structure. + +Signed-off-by: Ken Goldman + +diff --git a/utils/certifyx509.c b/utils/certifyx509.c +index ed42ac0..44640aa 100644 +--- a/utils/certifyx509.c ++++ b/utils/certifyx509.c +@@ -204,6 +204,7 @@ int main(int argc, char *argv[]) + setvbuf(stdout, 0, _IONBF, 0); /* output may be going through pipe to log file */ + TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "1"); + ++ curveID = curveID; /* no longer used, get from parent */ + /* command line argument defaults */ + for (i=1 ; (ivalidity->notBefore); + if (irc == 0) { + printf("createPartialCertificate: Error setting notBefore time\n"); +@@ -737,7 +734,6 @@ TPM_RC createPartialCertificate(TPM_PARTIAL_CERT *partialCertificate, /* input / + } + } + if (rc == 0) { +- notAfter = X509_get_notAfter(x509Certificate); + irc = X509_set1_notAfter(x509Certificate,partialCertificate->validity->notAfter); + if (irc == 0) { + printf("createPartialCertificate: Error setting notAfter time\n"); +-- +2.38.0 + diff --git a/ibmtss-utils-Update-certifyx509-for-Openssl-3.0.0.patch b/ibmtss-utils-Update-certifyx509-for-Openssl-3.0.0.patch new file mode 100644 index 0000000..dd599e3 --- /dev/null +++ b/ibmtss-utils-Update-certifyx509-for-Openssl-3.0.0.patch @@ -0,0 +1,1447 @@ +From 80fe9a2be93874a1606297e19539a741e23b20ce Mon Sep 17 00:00:00 2001 +From: Ken Goldman +Date: Mon, 23 Aug 2021 16:09:41 -0400 +Subject: utils: Update certifyx509 for Openssl 3.0.0 + +i2d_x509 no longer accepts a partial structure. Therefore, replace +the input and output parsers with the ASN.1 parsing macros. +Eliminated the custom DER parsing. Set the version from the TPM +output rather than hard coding to v3. + +Add x509 validity time compatibility functions to cryptutils.c + +Add -check_ss_sig to the regression test because openssl verify does +not verify the signature on self signed certificates. + +Signed-off-by: Ken Goldman + +diff --git a/utils/certifyx509.c b/utils/certifyx509.c +index 7e8ba8d..ed42ac0 100644 +--- a/utils/certifyx509.c ++++ b/utils/certifyx509.c +@@ -4,7 +4,7 @@ + /* Written by Ken Goldman */ + /* IBM Thomas J. Watson Research Center */ + /* */ +-/* (c) Copyright IBM Corporation 2019 - 2020. */ ++/* (c) Copyright IBM Corporation 2019 - 2021. */ + /* */ + /* All rights reserved. */ + /* */ +@@ -50,6 +50,11 @@ + #include + #include + ++#include ++#include ++#include ++#include ++ + #include "cryptoutils.h" + + #ifndef TPM_TSS_MBEDTLS +@@ -64,9 +69,74 @@ + /* NOTE: This is currently openssl only. */ + #include + ++/* definition of the partial certificate, from Part 3 TPM2_CertifyX509. ++ 1) Signature Algorithm Identifier (optional) ++ 2) Issuer (mandatory) ++ 3) Validity (mandatory) ++ 4) Subject Name (mandatory) ++ 5) Extensions (mandatory) ++*/ ++ ++typedef struct { ++ ASN1_TIME *notBefore; ++ ASN1_TIME *notAfter; ++} TPM_PARTIAL_CERT_VALIDITY; ++ ++/* partial certificate TPM input parameter entire structure */ ++typedef struct { ++ X509_ALGOR *algorithm; /* signature algorithm */ ++ X509_NAME *issuer; ++ TPM_PARTIAL_CERT_VALIDITY *validity; ++ X509_NAME *subject; ++ STACK_OF(X509_EXTENSION) *extensions; ++} TPM_PARTIAL_CERT; ++ ++ASN1_SEQUENCE(TPM_PARTIAL_CERT_VALIDITY) = { ++ ASN1_SIMPLE(TPM_PARTIAL_CERT_VALIDITY, notBefore, ASN1_TIME), ++ ASN1_SIMPLE(TPM_PARTIAL_CERT_VALIDITY, notAfter, ASN1_TIME), ++} ASN1_SEQUENCE_END(TPM_PARTIAL_CERT_VALIDITY) ++ ++/* the signature algorithm is optional while the extension list is mandatory */ ++ASN1_SEQUENCE(TPM_PARTIAL_CERT) = { ++ ASN1_OPT(TPM_PARTIAL_CERT, algorithm, X509_ALGOR), ++ ASN1_SIMPLE(TPM_PARTIAL_CERT, issuer, X509_NAME), ++ ASN1_SIMPLE(TPM_PARTIAL_CERT, validity, TPM_PARTIAL_CERT_VALIDITY), ++ ASN1_SIMPLE(TPM_PARTIAL_CERT, subject, X509_NAME), ++ ASN1_EXP_SEQUENCE_OF(TPM_PARTIAL_CERT, extensions, X509_EXTENSION, 3), ++} ASN1_SEQUENCE_END(TPM_PARTIAL_CERT) ++ ++DECLARE_ASN1_FUNCTIONS(TPM_PARTIAL_CERT) ++IMPLEMENT_ASN1_FUNCTIONS(TPM_PARTIAL_CERT) ++ ++/* add to signature TPM output parameter */ ++ ++typedef struct { ++ ASN1_INTEGER *version; ++ ASN1_INTEGER *serialNumber; ++ X509_ALGOR *signatureAlgorithm; ++ X509_PUBKEY *key; ++} TPM_ADDTOCERT; ++ ++ASN1_SEQUENCE(TPM_ADDTOCERT) = { ++ ASN1_EXP_OPT(TPM_ADDTOCERT, version, ASN1_INTEGER, 0), ++ ASN1_SIMPLE(TPM_ADDTOCERT, serialNumber, ASN1_INTEGER), ++ ASN1_SIMPLE(TPM_ADDTOCERT, signatureAlgorithm, X509_ALGOR), ++ ASN1_SIMPLE(TPM_ADDTOCERT, key, X509_PUBKEY), ++} ASN1_SEQUENCE_END(TPM_ADDTOCERT) ++ ++DECLARE_ASN1_FUNCTIONS(TPM_ADDTOCERT) ++IMPLEMENT_ASN1_FUNCTIONS(TPM_ADDTOCERT) ++ + static void printUsage(void); + +-TPM_RC createPartialCertificate(X509 *x509Certificate, ++TPM_RC addPartialCertExtension(TPM_PARTIAL_CERT *partialCertificate, ++ X509 *x509Certificate, ++ int nid, const char *value); ++TPM_RC addPartialCertExtensionTpmaOid(TPM_PARTIAL_CERT *partialCertificate, ++ X509 *x509Certificate, ++ uint32_t tpmaObject); ++TPM_RC createPartialCertificate(TPM_PARTIAL_CERT *certificate, ++ X509 *x509Certificate, + uint8_t *partialCertificateDer, + uint16_t *partialCertificateDerLength, + size_t partialCertificateDerSize, +@@ -74,22 +144,11 @@ TPM_RC createPartialCertificate(X509 *x509Certificate, + uint32_t tpmaObject, + int addTpmaObject, + int subeqiss); +-TPM_RC convertCertToPartialCert(uint16_t *partialCertificateDerLength, +- uint8_t *partialCertificateDer, +- uint16_t certificateDerLength, +- uint8_t *certificateDer); + TPM_RC reformCertificate(X509 *x509Certificate, + TPMI_ALG_HASH halg, + TPMI_ALG_SIG_SCHEME scheme, +- TPMI_ECC_CURVE curveID, +- TPM2B_MAX_BUFFER *addedToCertificate, +- TPMT_SIGNATURE *tSignature); +-TPM_RC addSerialNumber(X509 *x509Certificate, +- unsigned char *tmpAddedToCert, +- uint16_t *tmpAddedToCertIndex); +-TPM_RC addPubKeyRsa(X509 *x509Certificate, +- unsigned char *tmpAddedToCert, +- uint16_t *tmpAddedToCertIndex); ++ TPM_ADDTOCERT *addToCert, ++ TPMT_SIGNATURE *tSignature); + TPM_RC addSignatureRsa(X509 *x509Certificate, + TPMI_ALG_HASH halg, + TPMT_SIGNATURE *tSignature); +@@ -97,38 +156,10 @@ TPM_RC addSignatureRsa(X509 *x509Certificate, + TPM_RC addSignatureEcc(X509 *x509Certificate, + TPMI_ALG_HASH halg, + TPMT_SIGNATURE *signature); +-TPM_RC addPubKeyEcc(X509 *x509Certificate, +- unsigned char *tmpAddedToCert, +- uint16_t *tmpAddedToCertIndex, +- TPMI_ECC_CURVE curveID); + #endif /* TPM_TSS_NOECC */ +-TPM_RC addCertExtensionTpmaOid(X509 *x509Certificate, +- uint32_t tpmaObject); +- +-TPM_RC getDataLength(uint8_t type, +- uint16_t *wrapperLength, +- uint16_t *dataLength, +- uint16_t *certificateDerIndex, +- uint8_t *certificateDer); +- +-TPM_RC skipSequence(uint16_t *certificateDerIndex, uint8_t *certificateDer); +-TPM_RC skipBitString(uint16_t *dataLength, +- uint16_t *certificateDerIndex, uint8_t *certificateDer); +- +-TPM_RC copyType(uint8_t type, +- uint16_t *partialCertificateDerLength, uint8_t *partialCertificateDer, +- uint16_t *certificateDerIndex, uint8_t *certificateDer); +- +-TPM_RC getInteger(uint16_t *integerLength, unsigned char *integerStream, +- uint16_t *certificateDerIndex, unsigned char *certificateDer); +-TPM_RC prependSequence(uint16_t *partialCertificateDerLength, uint8_t *partialCertificateDer); + + int verbose = FALSE; + +-/* FIXME +- length checks +-*/ +- + int main(int argc, char *argv[]) + { + TPM_RC rc = 0; +@@ -145,8 +176,8 @@ int main(int argc, char *argv[]) + TPMI_ALG_HASH halg = TPM_ALG_SHA256; + unsigned int bit = 0; + int testBit = FALSE; +- const char *keyPassword = NULL; +- const char *objectPassword = NULL; ++ const char *keyPassword = NULL; ++ const char *objectPassword = NULL; + const char *outPartialCertificateFilename = NULL; + const char *outCertificateFilename = NULL; + const char *addedToCertificateFilename = NULL; +@@ -167,6 +198,8 @@ int main(int argc, char *argv[]) + X509 *x509Certificate = NULL; + unsigned char *x509Der = NULL; + uint32_t x509DerLength = 0; ++ TPM_PARTIAL_CERT *partialCertificate = NULL; ++ TPM_ADDTOCERT *addToCert = NULL; + + setvbuf(stdout, 0, _IONBF, 0); /* output may be going through pipe to log file */ + TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "1"); +@@ -453,9 +486,8 @@ int main(int argc, char *argv[]) + } + in.reserved.t.size = 0; + } +- /* initialize a new, empty X509 structure. It will first be used to form the partialCertificate +- command parameter, and then be used to reform the certificate from the response +- parameters. */ ++ /* initialize a new, empty X509 structure. It will be used to reform the certificate from ++ the response parameters. */ + if (rc == 0) { + x509Certificate = X509_new(); /* freed @1 */ + if (x509Certificate == NULL) { +@@ -463,9 +495,19 @@ int main(int argc, char *argv[]) + rc = TSS_RC_OUT_OF_MEMORY; + } + } +- /* form partial certificate */ ++ /* initialize a new, empty TPM_PARTIAL_CERT structure. It will be used to form the ++ partialCertificate command parameter */ ++ if (rc == 0) { ++ partialCertificate = TPM_PARTIAL_CERT_new(); /* freed @2 */ ++ if (partialCertificate == NULL) { ++ printf("main: Error in TPM_PARTIAL_CERT_new\n"); ++ rc = TSS_RC_OUT_OF_MEMORY; ++ } ++ } ++ /* form partial certificate and populate the X509 certificate with the values */ + if (rc == 0) { +- rc = createPartialCertificate(x509Certificate, ++ rc = createPartialCertificate(partialCertificate, ++ x509Certificate, + in.partialCertificate.t.buffer, + &in.partialCertificate.b.size, + sizeof(in.partialCertificate.t.buffer), +@@ -474,6 +516,7 @@ int main(int argc, char *argv[]) + addTpmaObject, + subeqiss); + } ++ /* for debug testing */ + if ((rc == 0) && (testBit)) { + unsigned int bitInByte = bit % 8; + unsigned int byteInDer = bit / 8; +@@ -481,7 +524,7 @@ int main(int argc, char *argv[]) + if (verbose) { + printf("main: Testing byte %u bit %u\n", byteInDer, bitInByte); + printf("main: Byte was %02x\n", in.partialCertificate.t.buffer[byteInDer]); +- } ++ } + in.partialCertificate.t.buffer[byteInDer] ^= (1 << bitInByte); + if (verbose) printf("main: Byte is %02x\n", in.partialCertificate.t.buffer[byteInDer]); + } +@@ -530,17 +573,22 @@ int main(int argc, char *argv[]) + printf("%s%s%s\n", msg, submsg, num); + rc = EXIT_FAILURE; + } +- /* write response parameters for debug */ ++ /* ++ write response parameters for debug ++ */ ++ /* added to certificate */ + if ((rc == 0) && (addedToCertificateFilename != NULL)) { + rc = TSS_File_WriteBinaryFile(out.addedToCertificate.t.buffer, + out.addedToCertificate.t.size, + addedToCertificateFilename); + } ++ /* to be signed digest */ + if ((rc == 0) && (tbsDigestFilename != NULL)) { + rc = TSS_File_WriteBinaryFile(out.tbsDigest.t.buffer, + out.tbsDigest.t.size, + tbsDigestFilename); + } ++ /* signature */ + if ((rc == 0) && (signatureFilename != NULL)) { + rc = TSS_File_WriteStructure(&out.signature, + (MarshalFunction_t)TSS_TPMT_SIGNATURE_Marshalu, +@@ -549,11 +597,21 @@ int main(int argc, char *argv[]) + if (rc == 0) { + if (verbose) TSS_TPMT_SIGNATURE_Print(&out.signature, 0); + } +- /* reform the signed certificate from the original input plus the response parameters */ ++ /* convert the TPM output addedToCertificate DER to the OpenSSL structure */ ++ if (rc == 0) { ++ const unsigned char *tmpptr = out.addedToCertificate.t.buffer; ++ addToCert = d2i_TPM_ADDTOCERT(NULL, /* freed @3 */ ++ &tmpptr, out.addedToCertificate.t.size); ++ if (addToCert == NULL) { ++ printf("d2i_TPM_ADDTOCERT failed %p\n", addToCert); ++ rc = EXIT_FAILURE; ++ } ++ } ++ /* reform the signed certificate from the original X509 input plus the response parameters */ + if (rc == 0) { + rc = reformCertificate(x509Certificate, +- halg, scheme, curveID, +- &out.addedToCertificate, ++ halg, scheme, ++ addToCert, + &out.signature); + } + if (rc == 0) { +@@ -569,7 +627,8 @@ int main(int argc, char *argv[]) + if (x509Certificate != NULL) { + X509_free(x509Certificate); /* @1 */ + } +- free(x509Der); /* @2 */ ++ free(x509Der); /* @2 */ ++ free(addToCert); /* @3 */ + return rc; + } + +@@ -587,7 +646,7 @@ char *issuerEntries[] = { + "IBM" , + NULL , + "CA" , +- NULL ++ NULL + }; + + char *subjectEntries[] = { +@@ -597,22 +656,23 @@ char *subjectEntries[] = { + "IBM" , + NULL , + "Subject" , +- NULL ++ NULL + }; + +-/* createPartialCertificate() forms the partialCertificate DER. It starts with an empty X509 +- structure and adds the needed parameters. Then (in a total hack), converts the X509 structure to +- DER, parses the DER field by field, and outputs just the fields required for the +- partialCertificate parameter. ++/* createPartialCertificate() forms the partialCertificate DER. It starts with an empty X509 and ++ TPM_PARTIAL_CERT structures. It adds the needed parameters to both structures. It then ++ serializes the TPM_PARTIAL_CERT structure to partialCertificateDer; + + subeqiss FALSE: subject name is independent of issuer name + subeqiss TRUE: subject name is the same as the issuer name + */ + +-TPM_RC createPartialCertificate(X509 *x509Certificate, /* input / output */ ++TPM_RC createPartialCertificate(TPM_PARTIAL_CERT *partialCertificate, /* input / output */ ++ X509 *x509Certificate, /* input / output */ + uint8_t *partialCertificateDer, /* output */ + uint16_t *partialCertificateDerLength, +- size_t partialCertificateDerSize, ++ size_t partialCertificateDerSize, /* input, size of ++ partialCertificateDer */ + const char *keyUsage, + uint32_t tpmaObject, + int addTpmaObject, +@@ -626,40 +686,31 @@ TPM_RC createPartialCertificate(X509 *x509Certificate, /* input / output */ + X509_NAME *x509SubjectName = NULL;/* composite subject name, key/value pairs */ + size_t issuerEntriesSize = sizeof(issuerEntries)/sizeof(char *); + size_t subjectEntriesSize = sizeof(subjectEntries)/sizeof(char *); +- +- uint32_t certificateDerLength = 0; +- uint8_t *certificateDer = NULL; ++ ASN1_TIME *notBefore = NULL; ++ ASN1_TIME *notAfter = NULL; ++ uint8_t *tmpPartialDer = NULL; /* for the i2d */ + +- partialCertificateDerSize = partialCertificateDerSize; /* FIXME needs size check */ +- +- /* add certificate version X509 v3 */ +- if (rc == 0) { +- irc = X509_set_version(x509Certificate, 2L); /* value 2 == v3 */ +- if (irc != 1) { +- printf("createPartialCertificate: Error in X509_set_version\n"); +- rc = TSS_RC_X509_ERROR; +- } +- } + /* add issuer */ + if (rc == 0) { + if (verbose) printf("createPartialCertificate: Adding issuer, size %lu\n", +- (unsigned long)issuerEntriesSize); +- rc = createX509Name(&x509IssuerName, /* freed @1 */ ++ (unsigned long)issuerEntriesSize); ++ rc = createX509Name(&partialCertificate->issuer, /* freed @1 */ + issuerEntriesSize, + issuerEntries); + } + if (rc == 0) { +- irc = X509_set_issuer_name(x509Certificate, x509IssuerName); ++ irc = X509_set_issuer_name(x509Certificate, partialCertificate->issuer); + if (irc != 1) { + printf("createPartialCertificate: Error setting issuer\n"); + rc = TSS_RC_X509_ERROR; + } + } +- /* add validity */ ++ /* ++ validity before ++ */ + if (rc == 0) { +- /* can't fail, just returns a structure member */ +- ASN1_TIME *notBefore = X509_get_notBefore(x509Certificate); +- arc = X509_gmtime_adj(notBefore ,0L); /* set to today */ ++ /* set to today */ ++ arc = X509_gmtime_adj(partialCertificate->validity->notBefore ,0L); + if (arc == NULL) { + printf("createPartialCertificate: Error setting notBefore time\n"); + rc = TSS_RC_X509_ERROR; +@@ -667,20 +718,39 @@ TPM_RC createPartialCertificate(X509 *x509Certificate, /* input / output */ + } + if (rc == 0) { + /* can't fail, just returns a structure member */ +- ASN1_TIME *notAfter = X509_get_notAfter(x509Certificate); +- arc = X509_gmtime_adj(notAfter, CERT_DURATION); /* set to duration */ ++ notBefore = X509_get_notBefore(x509Certificate); ++ irc = X509_set1_notBefore(x509Certificate, partialCertificate->validity->notBefore); ++ if (irc == 0) { ++ printf("createPartialCertificate: Error setting notBefore time\n"); ++ rc = TSS_RC_X509_ERROR; ++ } ++ } ++ /* ++ validity after ++ */ ++ if (rc == 0) { ++ /* set to duration */ ++ arc = X509_gmtime_adj(partialCertificate->validity->notAfter, CERT_DURATION); + if (arc == NULL) { + printf("createPartialCertificate: Error setting notAfter time\n"); + rc = TSS_RC_X509_ERROR; + } + } ++ if (rc == 0) { ++ notAfter = X509_get_notAfter(x509Certificate); ++ irc = X509_set1_notAfter(x509Certificate,partialCertificate->validity->notAfter); ++ if (irc == 0) { ++ printf("createPartialCertificate: Error setting notAfter time\n"); ++ rc = TSS_RC_X509_ERROR; ++ } ++ } + /* add subject */ + if (rc == 0) { + /* normal case */ + if (!subeqiss) { + if (verbose) printf("createPartialCertificate: Adding subject, size %lu\n", + (unsigned long)subjectEntriesSize); +- rc = createX509Name(&x509SubjectName, /* freed @2 */ ++ rc = createX509Name(&partialCertificate->subject, /* freed @2 */ + subjectEntriesSize, + subjectEntries); + } +@@ -688,13 +758,13 @@ TPM_RC createPartialCertificate(X509 *x509Certificate, /* input / output */ + else { + if (verbose) printf("createPartialCertificate: Adding subject (issuer), size %lu\n", + (unsigned long)issuerEntriesSize); +- rc = createX509Name(&x509SubjectName, /* freed @2 */ ++ rc = createX509Name(&partialCertificate->subject, /* freed @2 */ + issuerEntriesSize, + issuerEntries); + } + } + if (rc == 0) { +- irc = X509_set_subject_name(x509Certificate, x509SubjectName); ++ irc = X509_set_subject_name(x509Certificate, partialCertificate->subject); + if (irc != 1) { + printf("createPartialCertificate: Error setting subject\n"); + rc = TSS_RC_X509_ERROR; +@@ -703,109 +773,179 @@ TPM_RC createPartialCertificate(X509 *x509Certificate, /* input / output */ + /* add some certificate extensions, requires corresponding bits in subject key */ + if (rc == 0) { + if (verbose) printf("createPartialCertificate: Adding extensions\n"); +- rc = addCertExtension(x509Certificate, +- NID_key_usage, keyUsage); ++ rc = addPartialCertExtension(partialCertificate, ++ x509Certificate, ++ NID_key_usage, keyUsage); + } + /* optional TPMA_OBJECT extension */ + /* From TCG OID registry tcg-tpmaObject 2.23.133.10.1.1.1 */ + if (rc == 0) { + if (addTpmaObject) { +- rc = addCertExtensionTpmaOid(x509Certificate, tpmaObject); ++ rc = addPartialCertExtensionTpmaOid(partialCertificate, ++ x509Certificate, ++ tpmaObject); + } + } +- /* convertX509ToDer() serializes the openSSL X509 structure to a DER certificate stream */ ++ /* serialize the openSSL partial certificate structure to a DER stream */ ++ if (rc == 0) { ++ *partialCertificateDerLength = ++ (uint16_t)i2d_TPM_PARTIAL_CERT(partialCertificate, ++ &tmpPartialDer); /* freed @3 */ ++ } ++ /* check the i2d size, and copy the DER to the TPM input parameter */ + if (rc == 0) { +- rc = convertX509ToDer(&certificateDerLength, +- &certificateDer, /* freed @4 */ +- x509Certificate); /* input */ ++ if (*partialCertificateDerLength <= partialCertificateDerSize) { ++ memcpy(partialCertificateDer, tmpPartialDer, *partialCertificateDerLength); ++ } ++ else { ++ printf("createPartialCertificate: Partial cert size %u too large\n", ++ *partialCertificateDerLength); ++ rc = TSS_RC_X509_ERROR; ++ } + } +- /* for debug. The structure is incomplete and so will trace with errors */ ++#if 0 ++ /* for debug. The X509 structure is incomplete and so will trace with errors */ + if (rc == 0) { + if (verbose) printf("createPartialCertificate: Trace preliminary certificate\n"); + if (verbose) X509_print_fp(stdout, x509Certificate); + } +-#if 1 +- /* for debug. Use dumpasn1 to view the incomplete certificate */ ++#endif ++ X509_NAME_free(x509IssuerName); /* @1 */ ++ X509_NAME_free(x509SubjectName); /* @2 */ ++ free(tmpPartialDer); /* @3 */ ++ return rc; ++} ++ ++/* addPartialCertExtension() adds the extension type 'nid' to the partial certificate ++ ++ */ ++ ++TPM_RC addPartialCertExtension(TPM_PARTIAL_CERT *partialCertificate, ++ X509 *x509Certificate, ++ int nid, const char *value) ++{ ++ TPM_RC rc = 0; ++ X509_EXTENSION *extension = NULL; /* freed @1 */ ++ ++ if (rc == 0) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000 ++ /* the cast is required for the older openssl 1.0 API */ ++ extension = X509V3_EXT_conf_nid(NULL, NULL, /* freed @1 */ ++ nid, (char *)value); ++#else ++ extension = X509V3_EXT_conf_nid(NULL, NULL, /* freed @1 */ ++ nid, value); ++#endif ++ if (extension == NULL) { ++ printf("addPartialCertExtension: Error creating nid %i extension %s\n", ++ nid, value); ++ rc = -1; ++ } ++ } + if (rc == 0) { +- rc = TSS_File_WriteBinaryFile(certificateDer, certificateDerLength , "tmpx509i.bin"); ++ STACK_OF(X509_EXTENSION) *src = ++ X509v3_add_ext(&partialCertificate->extensions, ++ extension, /* the extension to add */ ++ -1); /* location - append */ ++ if (src == NULL) { ++ printf("addPartialCertExtension: Error adding nid %i extension %s\n", ++ nid, value); ++ } + } +-#endif +- /* extract the partialCertificate DER from the X509 DER */ + if (rc == 0) { +- rc = convertCertToPartialCert(partialCertificateDerLength, +- partialCertificateDer, /* output partial */ +- certificateDerLength, +- certificateDer); /* input X509 */ ++ int irc = X509_add_ext(x509Certificate, ++ extension, /* the extension to add */ ++ -1); /* location - append */ ++ if (irc != 1) { ++ printf("addCertExtension: Error adding oid to extension\n"); ++ } ++ } ++ if (extension != NULL) { ++ X509_EXTENSION_free(extension); /* @1 */ + } +- X509_NAME_free(x509IssuerName); /* @1 */ +- X509_NAME_free(x509SubjectName); /* @2 */ +- free(certificateDer); /* @4 */ + return rc; + } + +-/* addCertExtension() adds the tpmaObject extension oid to the X509 certificate ++/* addPartialCertExtensionTpmaOid() adds the tpmaObject extension oid to the X509 certificate + +- */ ++ */ + +-TPM_RC addCertExtensionTpmaOid(X509 *x509Certificate, uint32_t tpmaObject) ++TPM_RC addPartialCertExtensionTpmaOid(TPM_PARTIAL_CERT *partialCertificate, ++ X509 *x509Certificate, ++ uint32_t tpmaObject) + { + TPM_RC rc = 0; + X509_EXTENSION *extension = NULL; /* freed @1 */ + + + uint8_t tpmaObjectOid[] = {0x06, 0x07, 0x67, 0x81, 0x05, 0x0A, 0x01, 0x01, 0x01}; +- const uint8_t *tmpOidPtr; ++ const uint8_t *tmpOidPtr; /* const for d2i_ASN1_OBJECT */ + + /* BIT STRING 0x03 length 5 no padding 0, 4 dummy bytes of TPMA_OBJECT */ + uint8_t tpmaObjectData[] = {0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}; + ASN1_OBJECT *object = NULL; +- ASN1_OCTET_STRING *osData = NULL; ++ ASN1_OCTET_STRING *osData = NULL; + uint8_t *tmpOdPtr; + uint32_t tpmaObjectNbo = htonl(tpmaObject); + ++ ++ /* create the object */ + if (rc == 0) { +- tmpOidPtr = tpmaObjectOid; ++ tmpOidPtr = tpmaObjectOid; + object = d2i_ASN1_OBJECT(NULL, &tmpOidPtr, sizeof(tpmaObjectOid)); /* freed @2 */ + if (object == NULL) { +- printf("d2i_ASN1_OBJECT failed\n"); ++ printf("addPartialCertExtensionTpmaOid: d2i_ASN1_OBJECT failed\n"); + rc = TSS_RC_X509_ERROR; + } + } + if (rc == 0) { + osData = ASN1_OCTET_STRING_new(); /* freed @3 */ + if (osData == NULL) { +- printf("d2i_ASN1_OCTET_STRING failed\n"); ++ printf("addPartialCertExtensionTpmaOid: ASN1_OCTET_STRING_new failed\n"); + rc = TSS_RC_X509_ERROR; + } + } ++ /* copy the TPMA_OBJECT bytes to the BIT STRING place holder, set the result in the ++ ASN1_OCTET_STRING */ + if (rc == 0) { + tmpOdPtr = tpmaObjectData; + memcpy(tmpOdPtr + 3, &tpmaObjectNbo, sizeof(uint32_t)); + ASN1_OCTET_STRING_set(osData, tmpOdPtr, sizeof (tpmaObjectData)); + } ++ /* create the extension with the TPMA_OBJECT in the ASN1_OBJECT */ + if (rc == 0) { + extension = X509_EXTENSION_create_by_OBJ(NULL, /* freed @1 */ + object, +- 0, /* int crit */ ++ 0, /* int crit */ + osData); + if (extension == NULL) { +- printf("X509_EXTENSION_create_by_OBJ failed\n"); ++ printf("addPartialCertExtensionTpmaOid: X509_EXTENSION_create_by_OBJ failed\n"); + rc = TSS_RC_X509_ERROR; + } + } ++ /* append the extensions to the partial certificate stack */ ++ if (rc == 0) { ++ STACK_OF(X509_EXTENSION) *src = X509v3_add_ext(&partialCertificate->extensions, ++ extension, /* the extension to add */ ++ -1); /* location - append */ ++ if (src == NULL) { ++ printf("addPartialCertExtensionTpmaOid: Error adding oid to extension\n"); ++ } ++ } ++ /* append the extensions to the X509 certificate */ + if (rc == 0) { +- int irc = X509_add_ext(x509Certificate, /* the certificate */ ++ int irc = X509_add_ext(x509Certificate, /* the certificate */ + extension, /* the extension to add */ + -1); /* location - append */ + if (irc != 1) { +- printf("addCertExtension: Error adding oid to extension\n"); ++ printf("addPartialCertExtensionTpmaOid: Error adding oid to extension\n"); + } + } + if (extension != NULL) { + X509_EXTENSION_free(extension); /* @1 */ + } + if (object != NULL) { +- ASN1_OBJECT_free(object); /* @2 */ ++ ASN1_OBJECT_free(object); /* @2 */ + } + if (osData != NULL) { + ASN1_OCTET_STRING_free(osData); /* @3 */ +@@ -813,327 +953,95 @@ TPM_RC addCertExtensionTpmaOid(X509 *x509Certificate, uint32_t tpmaObject) + return rc; + } + +- +-/* convertCertToPartialCert() extracts the partialCertificate DER from the X509 DER +- +- It assumes that the input is well formed and has exactly the fields required. +-*/ +- +-TPM_RC convertCertToPartialCert(uint16_t *partialCertificateDerLength, +- uint8_t *partialCertificateDer, +- uint16_t certificateDerLength, +- uint8_t *certificateDer) +-{ +- TPM_RC rc = 0; +- uint16_t certificateDerIndex = 0; /* index into the DER input */ +- +- +- certificateDerLength = certificateDerLength; /* FIXME for future error checking */ +- *partialCertificateDerLength = 0; /* updates on each call */ +- +- /* skip the outer SEQUENCE wrapper */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Skip outer SEQUENCE wrapper\n"); +- rc = skipSequence(&certificateDerIndex, certificateDer); +- } +- /* skip the inner SEQUENCE wrapper, will be back filled with the total length */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Skip inner SEQUENCE wrapper\n"); +- rc = skipSequence(&certificateDerIndex, certificateDer); +- } +- /* skip the a3 wrapping the version */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Skip a3 version wrapper\n"); +- rc = copyType(0xa0, NULL, NULL, /* NULL says to skip */ +- &certificateDerIndex, certificateDer); +- } +- /* skip the integer (version) */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Skip version\n"); +- rc = copyType(0x02, NULL, NULL, /* NULL says to skip */ +- &certificateDerIndex, certificateDer); +- } +- /* skip the sequence (serial number) */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Skip serial number\n"); +- rc = copyType(0x30, NULL, NULL, /* NULL says to skip */ +- &certificateDerIndex, certificateDer); +- } +- /* copy the next SEQUENCE, issuer */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Copy issuer\n"); +- rc = copyType(0x30, partialCertificateDerLength, partialCertificateDer, +- &certificateDerIndex, certificateDer); +- } +- /* copy the next SEQUENCE, validity */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Copy validity\n"); +- rc = copyType(0x30, partialCertificateDerLength, partialCertificateDer, +- &certificateDerIndex, certificateDer); +- } +- /* copy the next SEQUENCE, subject */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Copy subject\n"); +- rc = copyType(0x30, partialCertificateDerLength, partialCertificateDer, +- &certificateDerIndex, certificateDer); +- } +- /* skip the SEQUENCE (public key) */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Skip public key\n"); +- rc = copyType(0x30, NULL, NULL, /* NULL says to skip */ +- &certificateDerIndex, certificateDer); +- } +- /* copy the a3 and encapsulating sequence */ +- if (rc == 0) { +- if (verbose) printf("convertCertToPartialCert: Copy a3 extensions\n"); +- rc = copyType(0xa3, partialCertificateDerLength, partialCertificateDer, +- &certificateDerIndex, certificateDer); +- } +- /* shift and back fill the sequence length */ +- if (rc == 0) { +- rc = prependSequence(partialCertificateDerLength, partialCertificateDer); +- } +- return rc; +-} +- +-/* reformCertificate() starts with the X509 certificate used as the input partialCertificate +- parameter plus a few fields like the version. It adds the output addedToCertificate and +- signature values to reform the X509 certificate that the TPM signed. +-*/ ++/* reformCertificate() starts with the X509 certificate filled with the input partialCertificate ++ parameter. It adds the output addedToCertificate and signature values to reform the X509 ++ certificate that the TPM signed. */ + + TPM_RC reformCertificate(X509 *x509Certificate, + TPMI_ALG_HASH halg, + TPMI_ALG_SIG_SCHEME scheme, +- TPMI_ECC_CURVE curveID, +- TPM2B_MAX_BUFFER *addedToCertificate, ++ TPM_ADDTOCERT *addToCert, + TPMT_SIGNATURE *tSignature) + { + TPM_RC rc = 0; +- unsigned char *tmpAddedToCert = NULL; +- /* size_t tmpAddedToCertLength = 0; FIXME better to sanity check length */ +- +- /* the index increments, so this function must parse the addedToCertificate in its order */ +- uint16_t tmpAddedToCertIndex = 0; +- +- tmpAddedToCert = addedToCertificate->t.buffer; +- /* tmpAddedToCertLength = addedToCertificate->t.size; */ +- +- /* add serial number */ +- if (rc == 0) { +- rc = addSerialNumber(x509Certificate, +- tmpAddedToCert, +- &tmpAddedToCertIndex); +- } +- if (scheme == TPM_ALG_RSASSA) { +- /* add public key algorithm and public key */ +- if (rc == 0) { +- rc = addPubKeyRsa(x509Certificate, +- tmpAddedToCert, +- &tmpAddedToCertIndex); +- } +- /* add certificate signature */ +- if (rc == 0) { +- rc = addSignatureRsa(x509Certificate, halg, tSignature); ++ int irc; ++ long versionl; ++ EVP_PKEY *evpPubkey = NULL; /* EVP format public key to be certified */ ++ ++ /* version */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000 ++ /* Older openssl does not has the uint64 function. This function is deprecated but OK since ++ X509 certificates never have a negative version. */ ++ if (rc == 0) { ++ versionl= ASN1_INTEGER_get(addToCert->version); ++ if (versionl < 0) { ++ printf("reformCertificate: Error in ASN1_INTEGER_get version\n"); ++ rc = TSS_RC_X509_ERROR; + } + } +-#ifndef TPM_TSS_NOECC +- else { /* scheme == TPM_ALG_ECDSA */ +- /* add public key */ +- if (rc == 0) { +- rc = addPubKeyEcc(x509Certificate, +- tmpAddedToCert, +- &tmpAddedToCertIndex, +- curveID); ++#else ++ if (rc == 0) { ++ uint64_t version64; ++ irc = ASN1_INTEGER_get_uint64(&version64, addToCert->version); ++ if (irc != 1) { ++ printf("reformCertificate: Error in ASN1_INTEGER_get_uint64 version\n"); ++ rc = TSS_RC_X509_ERROR; + } +- /* add certificate signature */ +- if (rc == 0) { +- rc = addSignatureEcc(x509Certificate, halg, tSignature); ++ else if (version64 > LONG_MAX) { ++ printf("reformCertificate: Version out of range\n"); ++ rc = TSS_RC_X509_ERROR; ++ } ++ else { ++ versionl = (long)version64; + } + } +-#endif /* TPM_TSS_NOECC */ +- return rc; +-} +- +-/* addSerialNumber() is the first call from reforming the certificate. tmpAddedToCertIndex will be +- 0. +- +- After the call, tmpAddedToCertIndex will point after the serial number. +-*/ +- +-TPM_RC addSerialNumber(X509 *x509Certificate, +- unsigned char *tmpAddedToCert, +- uint16_t *tmpAddedToCertIndex) +-{ +- TPM_RC rc = 0; +- ASN1_INTEGER *x509Serial; /* certificate serial number in ASN1 */ +- BIGNUM *x509SerialBN; /* certificate serial number as a BIGNUM */ +- unsigned char x509SerialBin[1048]; /* certificate serial number in binary */ +- uint16_t integerLength = 0; +- +- /* FIXME check the size */ +- +- x509SerialBN = NULL; +- +- /* skip outer sequence */ +- if (rc == 0) { +- rc = skipSequence(tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* skip version */ +- if (rc == 0) { +- rc = copyType(0xa0, NULL, NULL, /* NULL says to skip */ +- tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* get integer serial number from addedToCertificate */ +- if (rc == 0) { +- rc = getInteger(&integerLength, x509SerialBin, +- tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* convert the integer stream to a BIGNUM */ ++#endif + if (rc == 0) { +- x509SerialBN = BN_bin2bn(x509SerialBin, integerLength, x509SerialBN); /* freed @1 */ +- if (x509SerialBN == NULL) { +- printf("addSerialNumber: Error in serial number BN_bin2bn\n"); ++ irc = X509_set_version(x509Certificate, versionl); ++ if (irc != 1) { ++ printf("reformCertificate: Error in X509_set_version\n"); + rc = TSS_RC_X509_ERROR; + } + } +- /* add it into the final certificate */ ++ /* serial number */ + if (rc == 0) { +- /* get the serial number structure member, can't fail */ +- x509Serial = X509_get_serialNumber(x509Certificate); +- /* convert the BIGNUM to ASN1 and add to X509 certificate */ +- x509Serial = BN_to_ASN1_INTEGER(x509SerialBN, x509Serial); +- if (x509Serial == NULL) { +- printf("addSerialNumber: Error setting certificate serial number\n"); ++ irc = X509_set_serialNumber(x509Certificate, addToCert->serialNumber); ++ if (irc != 1) { ++ printf("reformCertificate: Error in X509_set_serialNumber\n"); + rc = TSS_RC_X509_ERROR; + } + } +- if (x509SerialBN != NULL) BN_clear_free(x509SerialBN ); /* @1 */ +- return rc; +-} +- +-/* addPubKeyRsa() adds the public key to the certificate. tmpAddedToCertIndex must point to the +- public key. +- */ +- +-TPM_RC addPubKeyRsa(X509 *x509Certificate, +- unsigned char *tmpAddedToCert, +- uint16_t *tmpAddedToCertIndex) +-{ +- TPM_RC rc = 0; +- TPM2B_PUBLIC_KEY_RSA tpm2bRsa; +- uint16_t dataLength; +- +- /* skip the SEQUENCE with the Signature Algorithm object identifier */ +- if (rc == 0) { +- rc = copyType(0x30, NULL, NULL, /* NULL says to skip */ +- tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* skip the SEQUENCE wrapper for the Subject Public Key Info */ +- if (rc == 0) { +- rc = skipSequence(tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* skip the SEQUENCE Public Key Algorithm */ +- if (rc == 0) { +- rc = copyType(0x30, NULL, NULL, /* NULL says to skip */ +- tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* skip the BIT STRING intoduction to the public key */ +- if (rc == 0) { +- rc = skipBitString(&dataLength, tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* skip the SEQUENCE wrapper for the public key */ +- if (rc == 0) { +- rc = skipSequence(tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* get the integer public modulus FIXME missing length check */ +- if (rc == 0) { +- rc = getInteger(&tpm2bRsa.t.size, tpm2bRsa.t.buffer, +- tmpAddedToCertIndex, tmpAddedToCert); +- } ++ /* public key including algorithm */ + if (rc == 0) { +- rc = addCertKeyRsa(x509Certificate, +- &tpm2bRsa); /* certified public key */ +- } +- /* skip the INTEGER public exponent - should not matter since it's the last item */ +- /* FIXME test for 010001 */ +- if (rc == 0) { +- uint16_t dummy; +- rc = getInteger(&dummy, NULL, +- tmpAddedToCertIndex, tmpAddedToCert); +- } +- return rc; +-} +- +-#ifndef TPM_TSS_NOECC +-/* addPubKeyEcc() adds the public key to the certificate. tmpAddedToCertIndex must point to the +- public key. +- +- Supports TPM_ECC_NIST_P256, TPM_ECC_NIST_P384. +-*/ +- +- +-TPM_RC addPubKeyEcc(X509 *x509Certificate, +- unsigned char *tmpAddedToCert, +- uint16_t *tmpAddedToCertIndex, +- TPMI_ECC_CURVE curveID) +-{ +- TPM_RC rc = 0; +- uint16_t dataLength; +- uint16_t pointSize; +- +- /* skip the SEQUENCE with the Signature Algorithm object identifier ecdsaWithSHAnnn */ +- if (rc == 0) { +- rc = copyType(0x30, NULL, NULL, /* NULL says to skip */ +- tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* skip the SEQUENCE wrapper for the Subject Public Key Info */ +- if (rc == 0) { +- rc = skipSequence(tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* skip the SEQUENCE Public Key Algorithm */ +- if (rc == 0) { +- rc = copyType(0x30, NULL, NULL, /* NULL says to skip */ +- tmpAddedToCertIndex, tmpAddedToCert); +- } +- /* skip the BIT STRING intoduction to the public key */ +- if (rc == 0) { +- rc = skipBitString(&dataLength, tmpAddedToCertIndex, tmpAddedToCert); ++ evpPubkey = X509_PUBKEY_get(addToCert->key); /* freed @1 */ ++ if (evpPubkey == NULL) { ++ printf("reformCertificate: X509_PUBKEY_get failed\n"); ++ rc = TSS_RC_OUT_OF_MEMORY; ++ } + } + if (rc == 0) { +- switch(curveID) { +- case TPM_ECC_NIST_P256: +- pointSize = 256/8; +- break; +- case TPM_ECC_NIST_P384: +- pointSize = 384/8; +- break; +- default: /* should never occur */ +- printf("addPubKeyEcc: Bad curveID %04x\n", curveID); +- rc = TSS_RC_BAD_SIGNATURE_ALGORITHM; +- break; ++ irc = X509_set_pubkey(x509Certificate, evpPubkey); ++ if (irc != 1) { ++ printf("reformCertificate: Error X509_set_pubkey failed\n"); ++ rc = TSS_RC_X509_ERROR; + } + } +- /* the next bytes are the 04, x and y */ ++ /* add certificate signature */ + if (rc == 0) { +- TPMT_PUBLIC tpmtPublic; +- +- *tmpAddedToCertIndex += 1; /* skip the 0x04 compression byte */ +- +- tpmtPublic.unique.ecc.x.t.size = pointSize; +- memcpy(tpmtPublic.unique.ecc.x.t.buffer, tmpAddedToCert + *tmpAddedToCertIndex, pointSize); +- *tmpAddedToCertIndex += pointSize; +- +- +- tpmtPublic.unique.ecc.y.t.size = pointSize; +- memcpy(tpmtPublic.unique.ecc.y.t.buffer, tmpAddedToCert + *tmpAddedToCertIndex, pointSize); +- *tmpAddedToCertIndex += pointSize; +- +- tpmtPublic.parameters.eccDetail.curveID = curveID; +- rc = addCertKeyEccT(x509Certificate, &tpmtPublic); ++ if (scheme == TPM_ALG_RSASSA) { ++ if (rc == 0) { ++ rc = addSignatureRsa(x509Certificate, halg, tSignature); ++ } ++ } ++ else { /* scheme == TPM_ALG_ECDSA */ ++ if (rc == 0) { ++ rc = addSignatureEcc(x509Certificate, halg, tSignature); ++ } ++ } + } ++ EVP_PKEY_free(evpPubkey); /* @1 **/ + return rc; + } +-#endif /* TPM_TSS_NOECC */ + + /* addSignatureRsa() copies the TPMT_SIGNATURE output of the TPM2_CertifyX509 command to the X509 + certificate. +@@ -1148,9 +1056,9 @@ TPM_RC addSignatureRsa(X509 *x509Certificate, + X509_ALGOR *signatureAlgorithm = NULL; + X509_ALGOR *certSignatureAlgorithm = NULL; + ASN1_BIT_STRING *asn1Signature = NULL; +- ++ + /* FIXME check sign length */ +- ++ + if (rc == 0) { + certSignatureAlgorithm = (X509_ALGOR *)X509_get0_tbs_sigalg(x509Certificate); + X509_get0_signature((OSSLCONST ASN1_BIT_STRING**)&asn1Signature, +@@ -1194,6 +1102,7 @@ TPM_RC addSignatureRsa(X509 *x509Certificate, + } + + #ifndef TPM_TSS_NOECC ++ + /* addSignatureEcc() copies the TPMT_SIGNATURE output of the TPM2_CertifyX509 command to the X509 + certificate. + */ +@@ -1214,7 +1123,7 @@ TPM_RC addSignatureEcc(X509 *x509Certificate, + int ecdsaSigBinLength; + + /* FIXME check sign length */ +- ++ + if (rc == 0) { + certSignatureAlgorithm = (X509_ALGOR *)X509_get0_tbs_sigalg(x509Certificate); + X509_get0_signature((OSSLCONST ASN1_BIT_STRING**)&asn1Signature, +@@ -1319,211 +1228,6 @@ TPM_RC addSignatureEcc(X509 *x509Certificate, + } + #endif /* TPM_TSS_NOECC */ + +-/* getDataLength() checks the type, gets the length of the wrapper and following data */ +- +-TPM_RC getDataLength(uint8_t type, /* expected type */ +- uint16_t *wrapperLength, /* wrapper */ +- uint16_t *dataLength, /* data */ +- uint16_t *certificateDerIndex, +- uint8_t *certificateDer) +-{ +- TPM_RC rc = 0; +- uint32_t i = 0; +- uint16_t lengthLength = 0; /* number of length bytes */ +- +- /* validate the wrapper type */ +- if (rc == 0) { +- if (certificateDer[*certificateDerIndex] != type) { +- printf("getDataLength: index %u expect %02x actual %02x\n", +- *certificateDerIndex, type, certificateDer[*certificateDerIndex]); +- rc = TSS_RC_X509_ERROR; +- } +- } +- /* get the length */ +- if (rc == 0) { +- /* long form length starts with the 'length of the length' */ +- if ((certificateDer[*certificateDerIndex + 1] & 0x80)) { +- lengthLength = certificateDer[*certificateDerIndex + 1] & 0x7f; +- if (lengthLength <= sizeof(*dataLength)) { +- +- *dataLength = 0; +- for (i = 0 ; i < lengthLength ; i++) { +- *dataLength <<= (i * 8); +- *dataLength += certificateDer[*certificateDerIndex + 2 + i]; +- } +- } +- else { +- printf("getDataLength: lengthLength %u too large for uint16_t\n", lengthLength); +- rc = TSS_RC_X509_ERROR; +- } +- } +- /* short form length is in byte following type */ +- else { +- *dataLength = certificateDer[*certificateDerIndex + 1] & 0x7f; +- } +- } +- if (rc == 0) { +- *wrapperLength = 2 + lengthLength; +- if (verbose) printf("getDataLength: wrapperLength %u dataLength %u\n", +- *wrapperLength, *dataLength); +- } +- return rc; +-} +- +-/* skipSequence() moves the certificateDerIndex past the SEQUENCE and its length. I.e., it just +- skips the wrapper, not the contents +-*/ +- +-TPM_RC skipSequence(uint16_t *certificateDerIndex, uint8_t *certificateDer) +-{ +- TPM_RC rc = 0; +- uint16_t wrapperLength; +- uint16_t dataLength; +- +- if (rc == 0) { +- rc = getDataLength(0x30, /* variable length SEQUENCE */ +- &wrapperLength, +- &dataLength, +- certificateDerIndex, certificateDer); +- } +- if (rc == 0) { +- *certificateDerIndex += wrapperLength; +- } +- return rc; +-} +- +-/* skipBitString() moves the certificateDerIndex past the BIT STRING, its length, and its padding, +- not the contents +-*/ +- +-TPM_RC skipBitString(uint16_t *dataLength, +- uint16_t *certificateDerIndex, uint8_t *certificateDer) +-{ +- TPM_RC rc = 0; +- uint16_t wrapperLength; +- +- if (rc == 0) { +- rc = getDataLength(0x03, /* BIT STRING */ +- &wrapperLength, +- dataLength, +- certificateDerIndex, certificateDer); +- } +- if (rc == 0) { +- *certificateDerIndex += wrapperLength; +- *certificateDerIndex += 1; /* BIT STRING padding */ +- } +- return rc; +-} +- +-/* copyType() copies the type at certificateDerIndex to partialCertificateDer. +- +- certificateDerIndex and partialCertificateDerLength are updated +-*/ +- +-TPM_RC copyType(uint8_t type, /* expected type */ +- uint16_t *partialCertificateDerLength, uint8_t *partialCertificateDer, +- uint16_t *certificateDerIndex, uint8_t *certificateDer) +-{ +- TPM_RC rc = 0; +- uint16_t wrapperLength = 0; +- uint16_t dataLength = 0; +- +- if (rc == 0) { +- rc = getDataLength(type, +- &wrapperLength, +- &dataLength, +- certificateDerIndex, certificateDer); +- } +- if (rc == 0) { +- if (partialCertificateDer != NULL) { +- memcpy(partialCertificateDer + *partialCertificateDerLength, +- &(certificateDer[*certificateDerIndex]), +- wrapperLength + dataLength); +- *partialCertificateDerLength += wrapperLength + dataLength; +- } +- *certificateDerIndex += wrapperLength + dataLength; +- } +- return rc; +-} +- +-/* getInteger() copies the INTEGER data (not including the wrapper) to integerStream. +- +- certificateDerIndex is updated. +-*/ +- +-TPM_RC getInteger(uint16_t *integerDataLength, unsigned char *integerStream, +- uint16_t *certificateDerIndex, unsigned char *certificateDer) +-{ +- TPM_RC rc = 0; +- uint16_t wrapperLength = 0; +- +- if (rc == 0) { +- rc = getDataLength(0x02, /* INTEGER */ +- &wrapperLength, +- integerDataLength, +- certificateDerIndex, certificateDer); +- } +- if (rc == 0) { +- if (integerStream != NULL) { +- memcpy(integerStream, +- certificateDer + *certificateDerIndex + wrapperLength, +- *integerDataLength); +- } +- *certificateDerIndex += wrapperLength + *integerDataLength; +- } +- return rc; +-} +- +-/* prependSequence() shifts the DER down and back fills the SEQUENCE and length */ +- +-TPM_RC prependSequence(uint16_t *partialCertificateDerLength, uint8_t *partialCertificateDer) +-{ +- TPM_RC rc = 0; +- uint16_t prefixLength; +- uint16_t lengthLength = 0; +- uint16_t i = 0; +- +- if (verbose) printf("prependSequence: total length %u %04x\n", +- *partialCertificateDerLength, *partialCertificateDerLength); +- /* calculate the number of prepended bytes */ +- if (rc == 0) { +- /* long form length when greater than 7f */ +- if ((*partialCertificateDerLength) > 0x7f) { +- lengthLength = (*partialCertificateDerLength / 0x100) + 1; /* +1 to round up */ +- prefixLength = 2 + lengthLength; /* SEQUENCE + length of length + length bytes */ +- } +- /* short form length when up to 7f */ +- else { +- prefixLength = 2; /* SEQUENCE + length byte */ +- } +- } +- /* shift the partialCertificateDer down by prefix length */ +- if (rc == 0) { +- memmove(partialCertificateDer + prefixLength, +- partialCertificateDer, +- *partialCertificateDerLength); +- } +- /* construct the prefix */ +- if (rc == 0) { +- partialCertificateDer[0] = 0x30; /* SEQUENCE */ +- /* long form length */ +- if (lengthLength > 0) { +- partialCertificateDer[1] = 0x80 + lengthLength; /* byte 1 bit 7 set for long form */ +- for (i = 0 ; i < lengthLength ; i++) { /* start at byte 2 */ +- partialCertificateDer[2 + i] = /* add length bytes */ +- (*partialCertificateDerLength >> ((lengthLength - i - 1) * 8)) & 0xff; +- } +- } +- /* short form length */ +- else { +- /* just length for short form, cast safe bacause of above test */ +- partialCertificateDer[1] = (uint8_t)*partialCertificateDerLength; +- } +- *partialCertificateDerLength += prefixLength; /* adjust the total length of the DER */ +- } +- return rc; +-} +- + static void printUsage(void) + { + printf("\n"); +@@ -1550,7 +1254,7 @@ static void printUsage(void) + printf("\t\te.g. decrypt: critical,dataEncipherment,keyAgreement,encipherOnly,decipherOnly\n"); + printf("\t\te.g. fixedTPM: critical,nonRepudiation\n"); + printf("\t\te.g. parent (restrict decrypt): critical,keyEncipherment\n"); +- ++ + printf("\t[-bit\tbit in partialCertificate to toggle]\n"); + printf("\t[-sub\tsubject same as issuer for self signed (root) certificate]\n"); + printf("\t[-opc\tpartial certificate file name (default do not save)]\n"); +@@ -1563,7 +1267,7 @@ static void printUsage(void) + printf("\t01\tcontinue\n"); + printf("\t20\tcommand decrypt\n"); + printf("\t40\tresponse encrypt\n"); +- exit(1); ++ exit(1); + } + + #endif /* TPM_TSS_MBEDTLS */ +diff --git a/utils/cryptoutils.c b/utils/cryptoutils.c +index 7c4e931..eb5f0d2 100644 +--- a/utils/cryptoutils.c ++++ b/utils/cryptoutils.c +@@ -4,7 +4,7 @@ + /* Written by Ken Goldman */ + /* IBM Thomas J. Watson Research Center */ + /* */ +-/* (c) Copyright IBM Corporation 2018 - 2020. */ ++/* (c) Copyright IBM Corporation 2018 - 2021. */ + /* */ + /* All rights reserved. */ + /* */ +@@ -160,6 +160,36 @@ void RSA_get0_factors(const RSA *rsaKey, + return; + } + ++static int ossl_x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm); ++ ++int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) ++{ ++ if (x == NULL) ++ return 0; ++ return ossl_x509_set1_time(&x->cert_info->validity->notBefore, tm); ++} ++ ++int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) ++{ ++ if (x == NULL) ++ return 0; ++ return ossl_x509_set1_time(&x->cert_info->validity->notAfter, tm); ++} ++ ++static int ossl_x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm) ++{ ++ ASN1_TIME *in; ++ in = *ptm; ++ if (in != tm) { ++ in = ASN1_STRING_dup(tm); ++ if (in != NULL) { ++ ASN1_TIME_free(*ptm); ++ *ptm = in; ++ } ++ } ++ return (in != NULL); ++} ++ + #endif /* pre openssl 1.1 */ + + /* These functions are only required for OpenSSL 1.0.1 OpenSSL 1.0.2 has them, and the structures +diff --git a/utils/cryptoutils.h b/utils/cryptoutils.h +index c2ddc6c..03452de 100644 +--- a/utils/cryptoutils.h ++++ b/utils/cryptoutils.h +@@ -4,7 +4,7 @@ + /* Written by Ken Goldman */ + /* IBM Thomas J. Watson Research Center */ + /* */ +-/* (c) Copyright IBM Corporation 2017 - 2019. */ ++/* (c) Copyright IBM Corporation 2017 - 2021. */ + /* */ + /* All rights reserved. */ + /* */ +@@ -225,6 +225,9 @@ extern "C" { + void RSA_get0_factors(const RSA *rsaKey, + const BIGNUM **p, + const BIGNUM **q); ++ int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); ++ int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); ++ EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key); + #endif /* pre openssl 1.1 */ + + #if OPENSSL_VERSION_NUMBER < 0x10002000 +diff --git a/utils/regtests/testx509.sh b/utils/regtests/testx509.sh +index 813085f..5640985 100755 +--- a/utils/regtests/testx509.sh ++++ b/utils/regtests/testx509.sh +@@ -73,8 +73,6 @@ do + checkSuccess $? + + +- # dumpasn1 -a -l -d tmpx509i.bin > tmpx509i1.dump +- # dumpasn1 -a -l -d -hh tmpx509i.bin > tmpx509i1.dumphh + # dumpasn1 -a -l -d tmppart1.bin > tmppart1.dump + # dumpasn1 -a -l -d -hh tmppart1.bin > tmppart1.dumphh + # dumpasn1 -a -l -d tmpadd1.bin > tmpadd1.dump +@@ -88,7 +86,7 @@ do + echo " INFO:" + + echo "Verify ${SALG[i]} self signed issuer root" +- openssl verify -CAfile tmpx5091.pem tmpx5091.pem > run.out 2>&1 ++ openssl verify -check_ss_sig -CAfile tmpx5091.pem tmpx5091.pem > run.out 2>&1 + grep -q OK run.out + checkSuccess $? + +@@ -96,8 +94,6 @@ do + ${PREFIX}certifyx509 -hk 80000001 -ho 80000002 -halg ${HALG[i]} -pwdk sig -pwdo sig -opc tmppart2.bin -os tmpsig2.bin -oa tmpadd2.bin -otbs tmptbs2.bin -ocert tmpx5092.bin ${SALG[i]} -iob 00040472 > run.out + checkSuccess $? + +- # dumpasn1 -a -l -d tmpx509i.bin > tmpx509i2.dump +- # dumpasn1 -a -l -d -hh tmpx509i.bin > tmpx509i2.dumphh + # dumpasn1 -a -l -d tmppart2.bin > tmppart2.dump + # dumpasn1 -a -l -d -hh tmppart2.bin > tmppart2.dumphhe + # dumpasn1 -a -l -d tmpadd2.bin > tmpadd2.dump +@@ -111,7 +107,7 @@ do + echo " INFO:" + + echo "Verify ${SALG[i]} subject against issuer" +- openssl verify -CAfile tmpx5091.pem tmpx5092.pem > run.out 2>&1 ++ openssl verify -check_ss_sig -CAfile tmpx5091.pem tmpx5092.pem > run.out 2>&1 + grep -q OK run.out + checkSuccess $? + +@@ -333,7 +329,6 @@ rm -r tmpsig1.bin + rm -r tmpx5091.bin + rm -r tmpx5091.pem + rm -r tmpx5092.pem +-rm -r tmpx509i.bin + rm -r tmppart2.bin + rm -r tmpadd2.bin + rm -r tmptbs2.bin +-- +2.38.0 + diff --git a/ibmtss.changes b/ibmtss.changes index 0893fcf..26380f6 100644 --- a/ibmtss.changes +++ b/ibmtss.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Wed Nov 9 13:33:51 UTC 2022 - Pedro Monreal + +- Build with OpenSSL 3.0 deprecated functions until fixed upstream +in the next version update [bsc#1205042] + * ibmtss-openssl3-deprecation.patch +- Add upstream patches to fix build with OpenSSL 3.0 + * ibmtss-regtests-Update-openssl-key-generation-for-3.0.0.patch + * ibmtss-utils-Update-certifyx509-for-Openssl-3.0.0.patch + * ibmtss-utils-Remove-unused-variables-from-certifyx509.patch + * ibmtss-tss-Port-HMAC-operations-to-openssl-3.0.patch + * ibmtss-utils-Port-to-openssl-3.0.0-replaces-RSA-with-EVP_PK.patch + ------------------------------------------------------------------- Thu Nov 25 11:48:53 UTC 2021 - Michal Suchanek diff --git a/ibmtss.spec b/ibmtss.spec index f4f7941..445b941 100644 --- a/ibmtss.spec +++ b/ibmtss.spec @@ -1,7 +1,7 @@ # # spec file for package ibmtss # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -32,6 +32,12 @@ URL: https://sourceforge.net/projects/ibmtpm20tss Source: https://sourceforge.net/projects/ibmtpm20tss/files/ibmtss%{version}.tar.gz Source1: 90-tpm-ibmtss.rules Patch1: ibmtss-configure.ac-Do-not-disable-optimization-for-debug-b.patch +Patch2: ibmtss-regtests-Update-openssl-key-generation-for-3.0.0.patch +Patch3: ibmtss-utils-Update-certifyx509-for-Openssl-3.0.0.patch +Patch4: ibmtss-utils-Remove-unused-variables-from-certifyx509.patch +Patch5: ibmtss-tss-Port-HMAC-operations-to-openssl-3.0.patch +Patch6: ibmtss-utils-Port-to-openssl-3.0.0-replaces-RSA-with-EVP_PK.patch +Patch7: ibmtss-openssl3-deprecation.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: ibmswtpm2