/*! \file 
**********************************************************************************
*Title:                         Discretix Toolkit Certificate Handling ATP Test source file
*
* Filename:                      CERT_TLK_ATP_OCSP.c 
*
* 
* Created:                      20.03.2008
*
*
* \Author                      Sagit Ben Tsur
*
* \Remarks
*           Copyright (C) 2008 by Discretix Technologies Ltd. All Rights reserved.
**********************************************************************************/
/************* Include Files *****************************************************/
#include "DX_VOS_BaseTypes.h"
#include "DX_VOS_TimeUtils.h"
#include "CERT_TLK_ATP_util.h"
#include "CERT_TLK_ATP_data.h"
#include "DX_VOS_Mem.h"
#include "CERT_TLK_ATP_tests.h"
#include "DX_VOS_Stdio.h"
#include "tlk_cert_api.h"
#include "MW_ATP_defines.h"
#include "MW_ATP_UTIL_funcs.h"
#include "CERT_TLK_ATP_util.h"
#include "tlk_sclk_api.h"

/*****************************************************************************
* Function Name:
*  TST_ATP_TLK_CERT_NonceIssuance
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return
*
* Description:
*    Test TLK_CERT_NonceIssuance
*  
* Algorithm: 
* 1. Call the API  TLK_CERT_NonceIssuance
* 2. Call the API  TLK_CERT_NonceIssuance again
* 3. Validate the nonce are different 

*******************************************************************************/  

DxError_t TST_ATP_TLK_CERT_NonceIssuance(void)
{
  
  DxError_t                  TST_Status;  
  TLK_CERT_Nonce_t           nonce1;
  TLK_CERT_Nonce_t           nonce2;
  DxChar_t                   TestName[] = "TST_ATP_TLK_CERT_NonceIssuance";


  TST_Status =  TLK_CERT_NonceIssuance(&nonce1,
                                       &TST_gServiceClockDesc,
                                       &TST_gServiceClockPwd,
                                       TST_gCWorkspace,
                                       TST_gCWorkspaceSizeInBytes);

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_NonceIssuance 1", TestName, TestName);

  TST_Status =  TLK_CERT_NonceIssuance(&nonce2,
                                      &TST_gServiceClockDesc,
                                      &TST_gServiceClockPwd, 
                                       TST_gCWorkspace,
                                       TST_gCWorkspaceSizeInBytes);
  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_NonceIssuance 2", TestName, TestName);

  if(0 == DX_VOS_MemCmp(&nonce1,&nonce2, sizeof(TLK_CERT_Nonce_t)))
    TST_Status = TST_FAIL; 
  else
    TST_Status = TST_PASS; 

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - nonce1 != nonce2", TestName, TestName);

  ATP_LOG_TST_PRINT((MW_ATP_MSG," **************************************************\n\n"));
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ** TST_ATP_TLK_CERT_NonceIssuance Test  PASS !!!  \n"));     
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ************************************************* \n \n"));

  return TST_PASS;
  EXIT_ON_ERROR:
  {
    return DX_FAILURE;
  }

}

/********************************************************************************************************************
* Function Name:                                                           
*  TST_ATP_TLK_CERT_ResponseProcess
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return                                        
*
* Description:                                                                 
*    Test TLK_CERT_ResponseProcess 
*  
* Algorithm:
* 1. Call TLK_CERT_ResponseProcess with: a valid OCSP  response, no nonce, a certificate to be checked ,
*    a Responder certificate and  a CA certificate  that issued the responder certificate  .
* 2. verify it returns TLK_CERT_RC_OK and the CERT_RV0 fields 
* 3. generate a new descriptor for secured service clock
* 4.Call TLK_CERT_NonceIssuance with Service clock descriptor generated in the previous call
* 5. Call TLK_CERT_ResponseProcess with:a valid OCSP  response ,a nonce, a certificate to be checked, 
*    no Responder certificate and CA certificate  that issued the responder certificate,
* 6. verify it returns TLK_CERT_RC_OK and the CERT_RV0 fields and time update 
* 7. Call TLK_CERT_ResponseProcess with: a valid OCSP response,a nonce,a certificate to be checked
*    a Responder certificate,and a CA certificate  that issued the responder certificate . 
* 8. verify it returns TLK_CERT_RC_OK and the CERT_RV0 fields 
*******************************************************************************************************************/ 
DxError_t TST_ATP_TLK_CERT_ResponseProcess(void)
{
   DxError_t                     TST_Status;
   TLK_CERT_Buffer_t             response_ptr ;
   TLK_CERT_Nonce_t              nonce;
   TLK_CERT_Buffer_t             certForCheck_ptr;
   TLK_CERT_Buffer_t             certResponder_ptr;
   TLK_CERT_Buffer_t             certCA_ptr;
   TLK_CERT_RV0_t                rvo_ptr;
   DxChar_t                      TestName[] = "TST_ATP_TLK_CERT_ResponseProcess";
   DxUint32_t                    maximumRevalidationPeriod;
   DxUint32_t                    maxAllowedDriftIn0_1Seconds;
   TLK_SCLK_ServiceClockTime_t   currTime;
   TLK_SCLK_ReadStatus_t         TST_ServiceStatus;
#ifndef TLK_CERT_NO_SCLK
  #ifdef SCLK_ON_SEP
    DxUint32_t    timeAddress;
 #endif
#endif

   maximumRevalidationPeriod     = 60;
   maxAllowedDriftIn0_1Seconds   = 0x1000;

  /*****************************/
  /* certificate to be checked */
  /*****************************/
   certForCheck_ptr.buff_ptr         = TST_gTBCCertificte;
   certForCheck_ptr.buffSizeInBytes  = TST_gTBCCertificteSize;

   /******************/
   /* CA certificate */
   /******************/
   certCA_ptr.buff_ptr               = TST_gTRCertificate; 
   certCA_ptr.buffSizeInBytes        = TST_gTRCertificateSize;

   /*************************/
   /* Responder certificate */
   /************************/
   certResponder_ptr.buff_ptr        = TST_g2Certificate;
   certResponder_ptr.buffSizeInBytes  = TST_g2CertificateSize;

   /****************/
   /* response_ptr */
   /***************/

   response_ptr.buff_ptr        = TST_gResOnTbcWithNoNonce;
   response_ptr.buffSizeInBytes = TST_gResOnTbcWithNoNonceSize; 

   /*Call TLK_CERT_ResponseProcess with
   a valid OCSP  response
   no nonce
   a certificate to be checked 
   a Responder certificate
   a CA certificate  that issued the responder certificate
   */

   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n****************************************************** \n"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"******** Response 1 ********"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A valid OCSP  response,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  No nonce,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A certificate to be checked,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A Responder certificate,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A CA certificate that issued the responder certificate \n"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"********************************************************* \n"));



   TST_Status =   TLK_CERT_ResponseProcess(&response_ptr,
                                           DX_NULL,
                                           &certForCheck_ptr,
                                           &certResponder_ptr,
                                           &certCA_ptr,
                                           &TST_gServClkDescNonceValid,
                                           &TST_gServClkDescNonceValidPwd,
                                           &TST_gServiceClockDesc,
                                           &TST_gServiceClockPwd,
                                           &rvo_ptr,
                                           TST_gCWorkspace,
                                           TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_ResponseProcess 1", TestName, TestName);


   /*The id of the certificate to be checked*/ 
   if(0 != DX_VOS_MemCmp(&TST_gCertIdentityTBC,&rvo_ptr.certIdentity, sizeof(DxSha1Result_t)))
    TST_Status = TST_FAIL; 
   else
    TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - rvo_ptr.certIdentity 1", TestName, TestName);

   /*The status of the verified response*/
   if(rvo_ptr.responseStatus != TST_gResStatus)
     TST_Status = TST_FAIL; 
   else
     TST_Status = TST_PASS;


   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp -  Response Status 1", TestName, TestName);


   /*The time is the time at which this response was signed - ProducedAt */
   if(0 != DX_VOS_MemCmp(&TST_gProducedAtOfTST_gResOnTbcWithNoNonce,&rvo_ptr.producedAt,sizeof(DxGeneralizedTime_t)))
     TST_Status = TST_FAIL; 
   else
     TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - rvo_ptr.producedAt 1", TestName, TestName);

   /*The status of certificate to be checked*/
   if(rvo_ptr.certStatus != TST_gCertStatus)
     TST_Status = TST_FAIL; 
   else
     TST_Status = TST_PASS;

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp -  certificate Status 1", TestName, TestName);




   /* Call TLK_CERT_ResponseProcess with
    A valid OCSP  response 
    A nonce,
    A certificate to be checked,
    No Responder certificate,
    A CA certificate  that issued the responder certificate
   */
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n****************************************************** \n"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"******** Response 2 ********"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A valid OCSP  response,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A nonce,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A certificate to be checked,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  No Responder certificate,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A CA certificate  that issued the responder certificate \n"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"********************************************************* \n"));

   response_ptr.buff_ptr             = TST_gResOnTbcWithNonce; 
   response_ptr.buffSizeInBytes      = TST_gResOnTbcWithNonceSize;
   /*generate a new descriptor for secured service clock*/
   TST_Status = TLK_SCLK_ServiceClkGen(&TST_gServClkDescNonceValid,
                                       DX_NULL,
                                       maxAllowedDriftIn0_1Seconds,
                                       maximumRevalidationPeriod,
                                       TLK_SCLK_WORLD_READABLE,
                                       TST_gServiceClockPwd.buff_ptr,
                                       TST_gServiceClockPwd.buffSizeInBytes,
                                       TST_gCWorkspace,
                                       TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_SCLK_ServiceClkGen", TestName, TestName);



   /* Call TLK_CERT_NonceIssuance with Service clock descriptor generated in the previous call*/
   TST_Status =  TLK_CERT_NonceIssuance(&nonce,
                                        &TST_gServClkDescNonceValid,
                                        &TST_gServClkDescNonceValidPwd,
                                        TST_gCWorkspace,
                                        TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_NonceIssuance 2", TestName, TestName);

   /*update the signature on the response ( for test purpose only*/
   TST_Status = UpdateResponseSignature(response_ptr.buff_ptr,
                                        TST_ga67RSAPrivateKey,
                                       (DxUint8_t *)&nonce,
                                       sizeof(nonce));

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"UpdateResponseSignature", TestName, TestName);



   /*Call TLK_CERT_ResponseProcess*/
   TST_Status =   TLK_CERT_ResponseProcess(&response_ptr,
                                           &nonce,
                                           &certForCheck_ptr,
                                           DX_NULL,
                                           &certCA_ptr,
                                           &TST_gServClkDescNonceValid,
                                           &TST_gServClkDescNonceValidPwd,
                                           &TST_gServiceClockDesc,
                                           &TST_gServiceClockPwd,
                                           &rvo_ptr,
                                           TST_gCWorkspace,
                                           TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_ResponseProcess 2", TestName, TestName);

#ifndef TLK_CERT_NO_SCLK
   /*validate the time when this object was generated*/
   TST_Status  = TLK_SCLK_ServiceClkRead(&TST_gServiceClockDesc,
                                       DX_NULL,
                                       &currTime,
                                       TLK_SCLK_DATE_TIME_FORMAT,
                                       &TST_ServiceStatus,
                                       TST_gServiceClockPwd.buff_ptr,
                                       TST_gServiceClockPwd.buffSizeInBytes,TST_gCWorkspace,
                                       TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_SCLK_ServiceClkRead", TestName, TestName);

   /*The time is the time at which this response was signed - ProducedAt */
   if(0 != DX_VOS_MemCmp(&TST_gProducedAtOfResOnTbcWithNonce,&currTime.dateTimeFormat,sizeof(DxGeneralizedTime_t)))
     TST_Status = TST_FAIL; 
   else
     TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - ( currTime.dateTimeFormat == ProducedAt of response on with nonce)", TestName, TestName);

#endif
   /*The id of the certificate to be checked */ 
   if(0 != DX_VOS_MemCmp(&TST_gCertIdentityTBC,&rvo_ptr.certIdentity, sizeof(DxSha1Result_t)))
     TST_Status = TST_FAIL; 
   else
    TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - rvo_ptr.certIdentity 2", TestName, TestName);

   /*The status of the verified response*/
   if(rvo_ptr.responseStatus != TST_gResStatus)
     TST_Status = TST_FAIL; 
   else
     TST_Status = TST_PASS;

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp -  Response Status 2", TestName, TestName);

   /*The time is the time at which this response was signed - ProducedAt */
   if(0 != DX_VOS_MemCmp(&TST_gProducedAtOfResOnTbcWithNonce,&rvo_ptr.producedAt,sizeof(DxGeneralizedTime_t)))
     TST_Status = TST_FAIL; 
   else
     TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - rvo_ptr.producedAt", TestName, TestName);

   /*The status of certificate to be checked*/
   if(rvo_ptr.certStatus != TST_gCertStatus)
     TST_Status = TST_FAIL; 
   else
     TST_Status = TST_PASS;


   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - certificate Status 2", TestName, TestName);



   response_ptr.buff_ptr   = TST_gResOnTbcWithNonce;
   response_ptr.buffSizeInBytes  = TST_gResOnTbcWithNonceSize;

   /* Call TLK_CERT_ResponseProcess with
   a valid OCSP response,
   a nonce
   a certificate to be checked 
   a Responder certificate
   a CA certificate  that issued the responder certificate  
   */
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n****************************************************** \n"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"******** Response 3 ********"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A valid OCSP  response,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A nonce,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A certificate to be checked,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A Responder certificate,"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n  A CA certificate that issued the responder certificate \n"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG,"********************************************************* \n"));




   TST_Status =   TLK_CERT_ResponseProcess(&response_ptr,
                                          &nonce,
                                          &certForCheck_ptr,
                                          &certResponder_ptr,
                                          &certCA_ptr,
                                          &TST_gServClkDescNonceValid,
                                          &TST_gServClkDescNonceValidPwd,
                                          &TST_gServiceClockDesc,
                                          &TST_gServiceClockPwd,
                                          &rvo_ptr,
                                          TST_gCWorkspace,
                                          TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_ResponseProcess 3", TestName, TestName);

   /*The id of the certificate to be checked */ 
   if(0 != DX_VOS_MemCmp(&TST_gCertIdentityTBC,&rvo_ptr.certIdentity, sizeof(DxSha1Result_t)))
     TST_Status = TST_FAIL; 
   else
    TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - rvo_ptr.certIdentity 3", TestName, TestName);



  /*Response Status*/
  if(rvo_ptr.responseStatus != TST_gResStatus)
    TST_Status = TST_FAIL; 
  else
    TST_Status = TST_PASS;

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - Response Status 3", TestName, TestName);
 
  /*The time is the time at which this response was signed - ProducedAt */
  if(0 != DX_VOS_MemCmp(&TST_gProducedAtOfResOnTbcWithNonce,&rvo_ptr.producedAt,sizeof(DxGeneralizedTime_t)))
    TST_Status = TST_FAIL; 
  else
    TST_Status = TST_PASS; 

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - rvo_ptr.producedAt 3", TestName, TestName);

  /*The status of certificate to be checked*/
  if(rvo_ptr.certStatus != TST_gCertStatus)
    TST_Status = TST_FAIL; 
  else
    TST_Status = TST_PASS;

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp -  certificate Status 3", TestName, TestName);


  ATP_LOG_TST_PRINT((MW_ATP_MSG," *************************************************\n\n"));
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ** TST_ATP_TLK_CERT_ResponseProcess Test  PASS !!!  \n"));
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ************************************************ \n \n"));

  return TST_PASS;
  EXIT_ON_ERROR:
  {
    return DX_FAILURE;
  }
}

/*****************************************************************************
* Function Name:
*  TST_ATP_TLK_CERT_CertFromResponseExtract
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return
*
* Description:
*    Test TLK_CERT_CertFromResponseExtract 
*
* Algorithm:
* 1. Call TLK_CERT_CertFromResponseExtract.
* 2. Verify the filed in the certificate extracted are the same in the certificate in the response.
* 3. validate the nextUpdate field extracted is similar to the one in the certificate
*******************************************************************************/ 

DxError_t TST_ATP_TLK_CERT_CertFromResponseExtract(void)
{

  DxError_t                   TST_Status;
  TLK_CERT_Buffer_t           response;
  TLK_CERT_Buffer_t           cert;
  DxGeneralizedTime_t         exparationTime;
  DxChar_t                    TestName[] = "TST_ATP_TLK_CERT_CertFromResponseExtract";

  cert.buff_ptr = TST_gExtractedCertificte;
  cert.buffSizeInBytes = TST_gExtractedCertificteSize;

  response.buff_ptr = TST_gResOnTbcWithNonce;
  response.buffSizeInBytes = TST_gResOnTbcWithNonceSize;


  TST_Status =   TLK_CERT_CertFromResponseExtract(&response,
                                                 &cert, 
                                                 &exparationTime);


  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DTLK_CERT_CertFromResponseExtract", TestName, TestName);


  /*certificate size*/
  if(cert.buffSizeInBytes != TST_g2CertificateSize)
    TST_Status = TST_FAIL; 
  else
    TST_Status = TST_PASS; 

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"wrong certificate size", TestName, TestName);
 

  /*cert.buff_ptr*/
  if(0 != DX_VOS_MemCmp(TST_g2Certificate,cert.buff_ptr, TST_g2CertificateSize))
      TST_Status = TST_FAIL; 
  else
     TST_Status = TST_PASS; 

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - cert.buff_ptr", TestName, TestName);

  /*exparationTime*/
  if(0 != DX_VOS_MemCmp(&TST_gResOnTbcWithNoNonceNextUpdate,&exparationTime,sizeof( DxGeneralizedTime_t)))
    TST_Status = TST_FAIL; 
  else
    TST_Status = TST_PASS; 

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - exparationTime", TestName, TestName);


  ATP_LOG_TST_PRINT((MW_ATP_MSG," ************************************************************\n\n"));
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ** TST_ATP_TLK_CERT_CertFromResponseExtract Test  PASS !!!  \n"));
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ************************************************************ \n \n"));

  return TST_PASS;
  EXIT_ON_ERROR:
  
    return DX_FAILURE;
 
}
//#endif
