/*! \file 
**********************************************************************************
*Title:                         Discretix Toolkit Certificate Handling ATP Test source file
*
* Filename:                      CERT_TLK_ATP_1667_Certificate.c 
*
* 
* Created:                       23.02.2009
*
*
* \Author                        Tania Mirzin
*
* \Remarks
*           Copyright (C) 2008 by Discretix Technologies Ltd. All Rights reserved.
**********************************************************************************/
/************* Include Files ***********************************/
#include "DX_VOS_BaseTypes.h"
#include "DX_VOS_Stdio.h"
#include "DX_VOS_Mem.h"

#include "MW_ATP_defines.h"
#include "MW_ATP_UTIL_funcs.h"

#include "CERT_TLK_ATP_util.h"
#include "CERT_TLK_ATP_data.h"
#include "CERT_TLK_ATP_tests.h"

#include "tlk_cert_api_ieee_1667.h"
#include "tlk_cert_types_ieee_1667.h"


 /*****************************************************************************
  * Function Name:                                                           
  *  TST_ATP_TLK_CERT_1667_CertificateChainValidation
  * 
  * Inputs:
  *  None
  *
  * Outputs:
  *  DxError_t - Function error return                                        
  *
  * Description:                                                                 
  *    Test TLK_CERT_ChainValidationInit, TLK_CERT_ChainValidationProcess , TLK_CERT_ChainValidationTerminate and
  *  TLK_CERT_1667_WorkspaceSizeGet
  *  
  * Algorithm: 
  * 1.  Call TLK_CERT_1667_ChainValidationInit.
  * 2.  Call TLK_CERT_1667_ChainValidProcess with the root Ca. 
  * 3.  Call TLK_CERT_1667_ChainValidProcess 3 times on the sequence of the chain every time the API will get the updated context from
  *     the previous call.
  * 4.  Call TLK_CERT_1667_ChainValidTerminate 
  * 5.  Validate the TLK_CERT_1667_CPVO_t have the correct fields: subjectNameTR and issuerNameTR from the trusted root certificate
  *     subjectNameEE and issuerNameEE from the first certificate in the chain are the same and all other fields equal the fields
  *     from the certificate.    
  *******************************************************************************/ 
DxError_t TST_ATP_TLK_CERT_1667_CertificateChainValidation(void)
{
   DxError_t                     TST_Status;
   TLK_CERT_1667_ContextObj_t    contextObject;
   TLK_CERT_1667_CPVO_t          cvpoObject;

   DxChar_t                      TestName[] = "TST_ATP_TLK_CERT_1667_CertificateChainValidation";

   TLK_CERT_Buffer_t             currCertificate;
   TLK_CERT_Buffer_t             prevCertificate;



   /*1.Call TLK_CERT_1667_ChainValidationInit.*/
   TST_Status = TLK_CERT_1667_ChainValidationInit(&contextObject); 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_1667_ChainValidationInit",TestName,TestName)

   /*2.Call TLK_CERT_1667_ChainValidProcess with the root Ca.*/
   prevCertificate.buff_ptr        = DX_NULL;
   prevCertificate.buffSizeInBytes = 0;
   currCertificate.buff_ptr        = TST_gTRCertificate;
   currCertificate.buffSizeInBytes = TST_gTRCertificateSize;


   TST_Status = TLK_CERT_1667_ChainValidationProcess(&prevCertificate,
                                                    &currCertificate,
                                                    &contextObject,
                                                    TLK_CERT_1667_BEGIN,
                                                    TST_gCWorkspace,
                                                    TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_1667_ChainValidationProcess",TestName,TestName)

   /*3.Call TLK_CERT_1667_ChainValidationProcess 3 times on the sequence of the chain every time the API will get the updated 
   context from  the previous call.*/

   prevCertificate.buff_ptr        = TST_gTRCertificate;
   prevCertificate.buffSizeInBytes = TST_gTRCertificateSize;
   currCertificate.buff_ptr        = TST_g2Certificate;
   currCertificate.buffSizeInBytes = TST_g2CertificateSize;

   TST_Status = TLK_CERT_1667_ChainValidationProcess(&prevCertificate,
                                                    &currCertificate,
                                                    &contextObject,
                                                     TLK_CERT_1667_CONTINUE,
                                                     TST_gCWorkspace,
                                                     TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_1667_ChainValidationProcess",TestName,TestName)

   prevCertificate.buff_ptr        = TST_g2Certificate;
   prevCertificate.buffSizeInBytes = TST_g2CertificateSize;
   currCertificate.buff_ptr        = TST_g1Certificate;
   currCertificate.buffSizeInBytes = TST_g1CertificateSize;
   
   TST_Status = TLK_CERT_1667_ChainValidationProcess(&prevCertificate,
                                                    &currCertificate,
                                                    &contextObject,
                                                     TLK_CERT_1667_CONTINUE,
                                                     TST_gCWorkspace,
                                                     TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_1667_ChainValidationProcess",TestName,TestName)

   prevCertificate.buff_ptr        = TST_g1Certificate;
   prevCertificate.buffSizeInBytes = TST_g1CertificateSize;
   currCertificate.buff_ptr        = TST_gEECertificate;
   currCertificate.buffSizeInBytes = TST_gEECertificateSize;

   TST_Status =  TLK_CERT_1667_ChainValidationProcess(&prevCertificate,
                                                     &currCertificate,
                                                     &contextObject,
                                                      TLK_CERT_1667_FINAL,
                                                      TST_gCWorkspace,
                                                      TST_gCWorkspaceSizeInBytes);

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_1667_ChainValidationProcess",TestName,TestName)
  
   /*4.Call TLK_CERT_1667_ChainValidTerminate*/
   TST_Status = TLK_CERT_1667_ChainValidationTerminate(&contextObject,&cvpoObject);
               

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_CERT_1667ChainValidationTerminate",TestName,TestName)


   /*5.Validate the TLK_CERT_1667_CPVO_t have the correct fields: subjectNameTR and issuerNameTR from the trusted root 
    certificate,  subjectNameEE and issuerNameEE from the first certificate in the chain are the same and all 
    other fields equal the fields  from the certificate.*/


   /*subjectNameEE*/
   /*-------------*/
   if(0 != DX_VOS_MemCmp(&TST_gSubjectNameEE,&cvpoObject.cvpoPart.subjectNameEE, sizeof(TLK_CERT_BufferOffest_t)))
     TST_Status = TST_FAIL; 
   else
    TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - subjectNameEE", TestName, TestName)


   /*signatureTR*/
   /*-------------*/
   if(0 != DX_VOS_MemCmp(&TST_gSignatureTR,&cvpoObject.cvpoPart.signatureTR, sizeof(TLK_CERT_BufferOffest_t)))
    TST_Status = TST_FAIL; 
   else
    TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - signatureTR", TestName, TestName)


   /*subjectKeyIdentifierEE*/
   /*---------------------*/
   if(0 != DX_VOS_MemCmp(&TST_gSubjectKeyIdentifierEE,&cvpoObject.cvpoPart.subjectKeyIdentifierEE, sizeof(TLK_CERT_BufferOffest_t)))
    TST_Status = TST_FAIL; 
   else
    TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - subjectKeyIdentifierEE", TestName, TestName)


   /*subjectPublicKeyInfoEE*/
   /*---------------------*/
    if(0 != DX_VOS_MemCmp(&TST_gSubjectPublicKeyInfoEE,&cvpoObject.cvpoPart.subjectPublicKeyInfoEE,
                          2*sizeof(DxUint32_t)))
     TST_Status = TST_FAIL; 
    else
     TST_Status = TST_PASS; 
      
   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - subjectPublicKeyInfoEE", TestName, TestName)


   /*subjectNameTR*/
   /*--------------*/
   if(0 != DX_VOS_MemCmp(&TST_gSubjectNameTR,&cvpoObject.cvpoPart.subjectNameTR, sizeof(TLK_CERT_BufferOffest_t)))
     TST_Status = TST_FAIL; 
   else
     TST_Status = TST_PASS; 
     
   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - subjectNameTR", TestName, TestName)


   /*subjectKeyIdentifierTR*/
   /*---------------------*/
   if(0 != DX_VOS_MemCmp(&TST_gsubjectKeyIdentifierTR,&cvpoObject.cvpoPart.subjectKeyIdentifierTR, sizeof(TLK_CERT_BufferOffest_t)))
     TST_Status = TST_FAIL; 
    else
     TST_Status = TST_PASS; 

   TST_ATP_CHECK_ERROR_RETURN(TST_Status,"DX_VOS_MemCmp - subjectKeyIdentifierTR", TestName, TestName)

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

   return TST_PASS;

   EXIT_ON_ERROR:
    return TST_Status;

}
