// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 3: Commands
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include "InternalRoutines.h"
#include "Attest_spt_fp.h"
#include "Certify_fp.h"
//
//
//     Error Returns               Meaning
//
//     TPM_RC_KEY                  key referenced by signHandle is not a signing key
//     TPM_RC_SCHEME               inScheme is not compatible with signHandle
//     TPM_RC_VALUE                digest generated for inScheme is greater or has larger size than the
//                                 modulus of signHandle, or the buffer for the result in signature is too
//                                 small (for an RSA key); invalid commit status (for an ECC key with a
//                                 split scheme).
//
TPM_RC
TPM2_Certify(
   Certify_In      *in,             // IN: input parameter list
   Certify_Out     *out             // OUT: output parameter list
   )
{
   TPM_RC                 result;
   TPMS_ATTEST            certifyInfo;

// Command Output

   // Filling in attest information
   // Common fields
   result = FillInAttestInfo(in->signHandle,
                             &in->inScheme,
                             &in->qualifyingData,
                             &certifyInfo);
   if(result != TPM_RC_SUCCESS)
   {
       if(result == TPM_RC_KEY)
           return TPM_RC_KEY + RC_Certify_signHandle;
       else
           return RcSafeAddToResult(result, RC_Certify_inScheme);
   }
   // Certify specific fields
   // Attestation type
   certifyInfo.type = TPM_ST_ATTEST_CERTIFY;
   // Certified object name
   certifyInfo.attested.certify.name.t.size =
       ObjectGetName(in->objectHandle,
                     &certifyInfo.attested.certify.name.t.buffer);
   // Certified object qualified name
   ObjectGetQualifiedName(in->objectHandle,
                          &certifyInfo.attested.certify.qualifiedName);

   // Sign attestation structure. A NULL signature will be returned if
   // signHandle is TPM_RH_NULL. A TPM_RC_NV_UNAVAILABLE, TPM_RC_NV_RATE,
   // TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES error may be returned
   // by SignAttestInfo()
   result = SignAttestInfo(in->signHandle,
                           &in->inScheme,
                           &certifyInfo,
                           &in->qualifyingData,
                           &out->certifyInfo,
                           &out->signature);

   // TPM_RC_ATTRIBUTES cannot be returned here as FillInAttestInfo would already
   // have returned TPM_RC_KEY
   pAssert(result != TPM_RC_ATTRIBUTES);

   if(result != TPM_RC_SUCCESS)
       return result;

   // orderly state should be cleared because of the reporting of clock info
   // if signing happens
   if(in->signHandle != TPM_RH_NULL)
       g_clearOrderly = TRUE;

   return TPM_RC_SUCCESS;
}
