in client-library/src/Attestation/LinuxTpm/lib/Tss2Wrapper.cpp [561:617]
attest::EphemeralKey Tss2Wrapper::GetCertifiedKeyAndFlushHandle(const unique_c_ptr<TPM2B_PUBLIC>& outPubPtr, ESYS_TR primaryHandle)
{
TPM2B_DATA qualifyingData = { 0 };
TPMT_SIG_SCHEME inScheme;
inScheme.scheme = TPM2_ALG_NULL;
TPM2B_ATTEST* certifyInfo = NULL;
TPMT_SIGNATURE* signature = NULL;
auto signHandle = Tss2Util::HandleToEsys(*ctx, AIK_PUB_INDEX);
TSS2_RC ret = Esys_Certify(this->ctx->Get(),
primaryHandle,
signHandle.get(),
ESYS_TR_PASSWORD,
ESYS_TR_PASSWORD,
ESYS_TR_NONE,
&qualifyingData,
&inScheme,
&certifyInfo,
&signature
);
if (ret != TSS2_RC_SUCCESS) {
// Flush the key object from the tpm to make sure we are not consuming tpm memory.
Tss2Util::FlushObjectContext(*ctx, primaryHandle);
throw Tss2Exception("Failed to certify ephemeral key", ret);
}
// Store the object in a unique_c_ptr<> to manage clean up after use.
unique_c_ptr<TPM2B_ATTEST> certifyInfoPtr(certifyInfo);
unique_c_ptr<TPMT_SIGNATURE> certifyInfoSignaturePtr(signature);
// Flush the key object from the tpm to make sure we are not consuming tpm memory.
Tss2Util::FlushObjectContext(*ctx, primaryHandle);
size_t offset = 0;
std::vector<unsigned char> keyPub(sizeof(*outPubPtr), '\0');
ret = Tss2_MU_TPM2B_PUBLIC_Marshal(outPubPtr.get(), keyPub.data(), keyPub.size(), &offset);
if (ret != TSS2_RC_SUCCESS) {
throw Tss2Exception("Failed to marshal TPM2B_PUBLIC", ret);
}
// Shrink to fit.
keyPub.resize(offset);
attest::Buffer certifyInfoMarshaled(certifyInfoPtr->attestationData,
certifyInfoPtr->attestationData + certifyInfoPtr->size);
attest::Buffer certifyInfoSignatureMarshaled(certifyInfoSignaturePtr->signature.rsassa.sig.buffer,
certifyInfoSignaturePtr->signature.rsassa.sig.buffer +
certifyInfoSignaturePtr->signature.rsassa.sig.size);
attest::EphemeralKey ephemeralKey;
ephemeralKey.encryptionKey = keyPub;
ephemeralKey.certifyInfo = certifyInfoMarshaled;
ephemeralKey.certifyInfoSignature = certifyInfoSignatureMarshaled;
return ephemeralKey;
}