diff --git a/Makefile.am b/Makefile.am index c531141..4f84405 100644 --- a/Makefile.am +++ b/Makefile.am @@ -97,6 +97,7 @@ TESTS = $(TESTS_SHELL) $(check_PROGRAMS) TESTS_SHELL = test/list.sh \ test/rand.sh \ test/rsa_genrsa_check.sh \ + test/rsa_genrsa_check_handle.sh \ test/rsa_genpkey_sign.sh \ test/rsa_genpkey_sign_rawin.sh \ test/rsa_genpkey_auth_parent.sh \ @@ -117,6 +118,7 @@ TESTS_SHELL = test/list.sh \ test/rsapss_createak_tls_server.sh \ test/rsa_pki/rsa_pki.sh \ test/ec_genpkey_check.sh \ + test/ec_genpkey_check_handle.sh \ test/ec_genpkey_parameters.sh \ test/ec_genpkey_x509_cms.sh \ test/ecdsa_genpkey_sign_auth.sh \ diff --git a/src/tpm2-provider-pkey.c b/src/tpm2-provider-pkey.c index 9f7b34d..75825a9 100644 --- a/src/tpm2-provider-pkey.c +++ b/src/tpm2-provider-pkey.c @@ -8,6 +8,7 @@ #include #include +#include #include "tpm2-provider-pkey.h" @@ -74,9 +75,15 @@ tpm2_keydata_write(const TPM2_KEYDATA *keydata, BIO *bout, TPM2_PKEY_FORMAT form if (!tpk) return 0; - if (Tss2_MU_TPM2B_PRIVATE_Marshal(&keydata->priv, &privbuf[0], - sizeof(privbuf), &privbuf_len)) - goto error; + if (keydata->privatetype == KEY_TYPE_HANDLE) { + if (Tss2_MU_TPM2_HANDLE_Marshal(keydata->handle, &privbuf[0], + sizeof(TPM2_HANDLE), &privbuf_len)) + goto error; + } else { + if (Tss2_MU_TPM2B_PRIVATE_Marshal(&keydata->priv, &privbuf[0], + sizeof(privbuf), &privbuf_len)) + goto error; + } if (Tss2_MU_TPM2B_PUBLIC_Marshal(&keydata->pub, &pubbuf[0], sizeof(pubbuf), &pubbuf_len)) @@ -150,7 +157,12 @@ tpm2_keydata_read(BIO *bin, TPM2_KEYDATA *keydata, TPM2_PKEY_FORMAT format) if (tpk == NULL) return 0; - keydata->privatetype = KEY_TYPE_BLOB; + if (TPM2_ASN1_STRING_get_length(tpk->privkey) == sizeof(keydata->handle) + && ASN1_STRING_get0_data(tpk->privkey)[0] == TPM2_HT_PERSISTENT) + keydata->privatetype = KEY_TYPE_HANDLE; + else + keydata->privatetype = KEY_TYPE_BLOB; + keydata->emptyAuth = (tpk->emptyAuth != V_ASN1_UNDEF && tpk->emptyAuth); // the ASN1_INTEGER_get on a 32-bit machine will fail for numbers of UINT32_MAX @@ -171,10 +183,17 @@ tpm2_keydata_read(BIO *bin, TPM2_KEYDATA *keydata, TPM2_PKEY_FORMAT format) strcmp(type_oid, OID_loadableKey)) goto error; - if (Tss2_MU_TPM2B_PRIVATE_Unmarshal(ASN1_STRING_get0_data(tpk->privkey), - TPM2_ASN1_STRING_get_length(tpk->privkey), - NULL, &keydata->priv)) - goto error; + if (keydata->privatetype == KEY_TYPE_HANDLE) { + if (Tss2_MU_TPM2_HANDLE_Unmarshal(ASN1_STRING_get0_data(tpk->privkey), + TPM2_ASN1_STRING_get_length(tpk->privkey), + NULL, &keydata->handle)) + goto error; + } else { + if (Tss2_MU_TPM2B_PRIVATE_Unmarshal(ASN1_STRING_get0_data(tpk->privkey), + TPM2_ASN1_STRING_get_length(tpk->privkey), + NULL, &keydata->priv)) + goto error; + } if (Tss2_MU_TPM2B_PUBLIC_Unmarshal(ASN1_STRING_get0_data(tpk->pubkey), TPM2_ASN1_STRING_get_length(tpk->pubkey), diff --git a/test/ec_genpkey_check_handle.sh b/test/ec_genpkey_check_handle.sh new file mode 100755 index 0000000..1d85f0f --- /dev/null +++ b/test/ec_genpkey_check_handle.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: BSD-3-Clause +set -eufx + +# create EK +tpm2_createek -G ecc -c ek_ecc.ctx + +# create AK with defined scheme/hash +tpm2_createak -C ek_ecc.ctx -G ecc -g sha256 -s ecdsa -c ak_ecc.ctx + +# load the AK to persistent handle +HANDLE=$(tpm2_evictcontrol -c ak_ecc.ctx | cut -d ' ' -f 2 | head -n 1) + +# generate private key as PEM ans save it to tpm2 +openssl pkey -provider tpm2 -provider base -in handle:${HANDLE} -out tpmprivkey.pem + +# Generate public key from handle +openssl pkey -provider tpm2 -provider base -in tpmprivkey.pem -check -text -noout + +# Generate public key from tss2 private keyc +openssl pkey -provider tpm2 -provider base -in handle:${HANDLE} -check -text -noout + +# convert PEM private key to DER +openssl pkey -provider tpm2 -provider base -in tpmprivkey.pem -outform der -out testkey.der + +# convert PEM private key handle to DER +openssl pkey -provider tpm2 -provider base -in handle:${HANDLE} -outform der -out testkeyhandle.der + +# read PEM from stdin and export public key as PEM +cat tpmprivkey.pem | openssl pkey -provider tpm2 -provider base -pubout -out pubkey.pem + +# read PEM from handle and export public key as PEM +openssl pkey -provider tpm2 -provider base -in handle:${HANDLE} -pubout -out pubkeyhandle.pem + +# display public key info +openssl pkey -pubin -in pubkey.pem -text -noout +openssl pkey -pubin -in pubkeyhandle.pem -text -noout + +# release persistent handle +tpm2_evictcontrol -c ${HANDLE} + +rm testkey.der testkeyhandle.der pubkey.pem ek_ecc.ctx ak_ecc.ctx pubkeyhandle.pem tpmprivkey.pem diff --git a/test/rsa_genrsa_check_handle.sh b/test/rsa_genrsa_check_handle.sh new file mode 100755 index 0000000..d469ab0 --- /dev/null +++ b/test/rsa_genrsa_check_handle.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: BSD-3-Clause +set -eufx + +# create EK +tpm2_createek -G rsa -c ek_rsa.ctx + +# create AK with defined scheme/hash +tpm2_createak -C ek_rsa.ctx -G rsa -g sha256 -s rsassa -c ak_rsa.ctx + +# load the AK to persistent handle +HANDLE=$(tpm2_evictcontrol -c ak_rsa.ctx | cut -d ' ' -f 2 | head -n 1) + +# generate private key as PEM ans save it to tpm2 +openssl pkey -provider tpm2 -provider base -in handle:${HANDLE} -out tpmprivkey.pem + +# Generate public key from handle +openssl pkey -provider tpm2 -provider base -in tpmprivkey.pem -check -text -noout + +# Generate public key from tss2 private keyc +openssl pkey -provider tpm2 -provider base -in handle:${HANDLE} -check -text -noout + +# convert PEM private key to DER +openssl pkey -provider tpm2 -provider base -in tpmprivkey.pem -outform der -out testkey.der + +# convert PEM private key handle to DER +openssl pkey -provider tpm2 -provider base -in handle:${HANDLE} -outform der -out testkeyhandle.der + +# read PEM from stdin and export public key as PEM +cat tpmprivkey.pem | openssl pkey -provider tpm2 -provider base -pubout -out pubkey.pem + +# read PEM from handle and export public key as PEM +openssl pkey -provider tpm2 -provider base -in handle:${HANDLE} -pubout -out pubkeyhandle.pem + +# display public key info +openssl pkey -pubin -in pubkey.pem -text -noout +openssl pkey -pubin -in pubkeyhandle.pem -text -noout + +# release persistent handle +tpm2_evictcontrol -c ${HANDLE} + +rm testkey.der testkeyhandle.der pubkey.pem ek_rsa.ctx ak_rsa.ctx pubkeyhandle.pem tpmprivkey.pem