attest::EphemeralKey Tss2Wrapper::GetCertifiedKeyAndFlushHandle()

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;
}