/* ***************************************************************** *
 * Copyright 1998 International Business Machines Corporation. All   *
 * Rights Reserved.                                                  *
 *                                                                   *
 * Please read this carefully.  Your use of this reference           *
 * implementation of certain of the IETF public-key infrastructure   *
 * specifications ("Software") indicates your acceptance of the      *
 * following.  If you do not agree to the following, do not install  *
 * or use any of the Software.                                       *
 *                                                                   *
 * Permission to use, reproduce, distribute and create derivative    *
 * works from the Software ("Software Derivative Works"), and to     *
 * distribute such Software Derivative Works is hereby granted to    *
 * you by International Business Machines Corporation ("IBM").  This *
 * permission includes a license under the patents of IBM that are   *
 * necessarily infringed by your use of the Software as provided by  *
 * IBM.                                                              *
 *                                                                   *
 * IBM licenses the Software to you on an "AS IS" basis, without     *
 * warranty of any kind.  IBM HEREBY EXPRESSLY DISCLAIMS ALL         *
 * WARRANTIES OR CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING,   *
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF       *
 * MERCHANTABILITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR    *
 * PURPOSE.  You are solely responsible for determining the          *
 * appropriateness of using this Software and assume all risks       *
 * associated with the use of this Software, including but not       *
 * limited to the risks of program errors, damage to or loss of      *
 * data, programs or equipment, and unavailability or interruption   *
 * of operations.                                                    *
 *                                                                   *
 * IBM WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES OR FOR ANY SPECIAL, *
 * INCIDENTAL, OR  INDIRECT DAMAGES OR FOR ANY ECONOMIC              *
 * CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN   *
 * IF IBM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  IBM  *
 * will not be liable for the loss of, or damage to, your records or *
 * data, or any damages claimed by you based on a third party claim. *
 *                                                                   *
 * IBM wishes to obtain your feedback to assist in improving the     *
 * Software.  You grant IBM a world-wide, royalty-free right to use, *
 * copy, distribute, sublicense and prepare derivative works based   *
 * upon any feedback, including materials, error corrections,        *
 * Software Derivatives, enhancements, suggestions and the like that *
 * you provide to IBM relating to the Software (this does not        *
 * include products for which you charge a royalty and distribute to *
 * IBM under other terms and conditions).                            *
 *                                                                   *
 * You agree to distribute the Software and any Software Derivatives *
 * under a license agreement that: 1) is sufficient to notify all    *
 * licensees of the Software and Software Derivatives that IBM       *
 * assumes no liability for any claim that may arise regarding the   *
 * Software or Software Derivatives, and 2) that disclaims all       *
 * warranties, both express and implied, from IBM regarding the      *
 * Software and Software Derivatives.  (If you include this          *
 * Agreement with any distribution of the Software or Software       *
 * Derivatives you will have met this requirement.)  You agree that  *
 * you will not delete any copyright notices in the Software.        *
 *                                                                   *
 * This Agreement is the exclusive statement of your rights in the   *
 * Software as provided by IBM.   Except for the rights granted to   *
 * you in the second paragraph above, You are not granted any other  *
 * patent rights, including but not limited to the right to make     *
 * combinations of the Software with products that infringe IBM      *
 * patents. You agree to comply with all applicable laws and         *
 * regulations, including all export and import laws and regulation. *
 * This Agreement is governed by the laws of the State of New York.  *
 * This Agreement supersedes all other communications,               *
 * understandings or agreements we may have had prior to this        *
 * Agreement.                                                        *
 * ***************************************************************** */

/*************************************************************************
 *
 *  Module Name:
 *    jonahtp.cpp
 *
 *  Module Description:
 *    Jonah Trust Policy Library CDSA addin
 *
 *  Notes:
 *    Implement PKIX Draft 9, Section 6 certification path validation using
 *    CDSA TPI interfaces.
 *
 * TP_CertSign             Determines whether the signer's certificate 
 *                         is authorized to perform the signing operation. 
 *                         If so, The TP module carries out the operation. 
 *                         The scope of a signature may be used to identify 
 *                         which certificate field should be signed.
 * TP_CertRevoke           Determines whether the revoker's certificate is 
 *                         trusted to perform/sign the revocation. If so, 
 *                         the TP module carries out the operation by adding 
 *                         a new revocation record to the CRL.
 * TP_CertGroupConstruct   Constructs a collection of certificates that 
 *                         forms a semantically-related trust relationship.
 * TP_CertGroupVerify      Determines whether the certificate group is 
 *                         trustworthy. Policy identifiers are used to specify 
 *                         the policy domain(s) to be evaluated by the 
 *                         policy module.
 * TP_CertGroupPrune       Removes from a collection of certificates those 
 *                         that do not participate in a semantically-related 
 *                         trust relationship outside of the local system.
 * TP_CrlVerify            Determines whether the CRL is trusted. This test may 
 *                         include verifying the correctness of the signature 
 *                         associated with the CRL, determining whether the CRL 
 *                         has been tampered with, and determining if the agent 
 *                         who signed the CRL is a trusted issuer of CRLs.
 * TP_CrlSign              Determines whether the certificate is trusted to 
 *                         sign the CRL. If so, the TP module carries out 
 *                         the operation.
 * TP_ApplyCrlToDb         Determines whether the memory-resident CRL is 
 *                         trusted and should be applied to a persistent database, 
 *                         which could result in designating certificates as revoked.
 * TP_PassThrough          Executes TP module custom operations.  This 
 *                         function accepts as input an operation ID and an 
 *                         arbitrary set of input parameters. The operation 
 *                         ID may specify any type of operation the TP wishes 
 *                         to export. Such operations may include queries or 
 *                         services specific to the domain represented by the 
 *                         TP module.
 *
 *  Change History:
 *
 *  Item   Author   Date     Description
 *  ------ -------- -------- ----------------------------------------------
 *  Create IAM      7/23/98  Created.
 *
 *************************************************************************/


//------------------------------------------------------------
// includes
//------------------------------------------------------------

#include <stdio.h>
#include "cssmport.h"
#include "cssm.h"
#include "cssmspi.h"
#include "cssmtpi.h"
#include "cssmcspi.h"
#include "functiontrace.h"
#include "JonahIni.h"
#include "jonahtp.h"
#include "pkixvalidator.h"


//------------------------------------------------------------
// global data
//------------------------------------------------------------

CSSM_SPI_MEMORY_FUNCS UpcallTable = {NULL, NULL, NULL, NULL};
unsigned char JonahPolicy[]       = { JONAHTP_POLICY_OID_DATA };

// INI file variables

bool _iniUseCRLs = false;
bool _iniAllowExpiredCRLs = true;


// Jump Table Functions

//------------------------------------------------------------
// function: CertSign
//------------------------------------------------------------
/*
 * The TP module first decides whether the signer certificate 
 * group has the authority to perform the signing operation. 
 * Once trust is established, the TP signs the certificate 
 * template using the signer's certificate group and the SignScope.
 * 
 * Parameters
 * 
 * TPHandle (input)
 * The handle that describes the add-in trust policy module used 
 * to perform this function.
 * 
 * CLHandle (input/optional)
 * The handle that describes the add-in certificate library 
 * module used to perform this function.
 * 
 * CCHandle (input/optional)
 * The handle that describes a context for cryptographic 
 * operations. The cryptographic context specifies the handle 
 * of the cryptographic service provider (CSP) that must be 
 * used to perform the operation. If no cryptographic context 
 * is specified, the TP module uses an assumed context, if required.
 * 
 * DBList (input/optional)
 * A list of certificate databases containing certificates 
 * that may be used to construct the trust structure of 
 * the signer certificate group.
 * 
 * CertToBeSigned (input)
 * A pointer to the CSSM_DATA structure containing 
 * a certificate to be signed.
 * 
 * SignerCertGroup (input)
 * A pointer to the CSSM_CERTGROUP structure containing 
 * one or more related certificates used to sign the certificate.
 * 
 * SignScope (input/optional)
 * A pointer to the CSSM_FIELD array containing the tags 
 * of the certificate fields to be included in the signing 
 * process.  If the signing scope is null, the TP Module 
 * must assume a default scope (portions of the 
 * certificate to be hashed) when performing the signing process.
 * 
 * ScopeSize (input)
 * The number of entries in the sign scope list. 
 * If the signing scope is not specified, the input 
 * parameter value for scope size must be zero.
 * 
 * Return Value
 * A pointer to the CSSM_DATA structure containing the 
 * signed certificate.  If the pointer is NULL, an 
 * error has occurred. This function may return errors 
 * specific to CSP, CL and DL modules.
 * 
 * Error Codes
 * CSSM_TP_INVALID_DBLIST           Invalid DB list parameter passed
 * CSSM_TP_INVALID_CERTIFICATE      Invalid certificate 
 * CSSM_TP_CERTIFICATE_CANT_OPERATE Signer certificate can't sign subject
 * CSSM_TP_MEMORY_ERROR             Error in allocating memory
 * CSSM_TP_CERT_SIGN_FAIL           Unable to sign certificate
 * CSSM_TP_INVALID_TP_HANDLE        Invalid handle passed
 * CSSM_TP_INVALID_CL_HANDLE        Invalid handle passed
 * CSSM_TP_INVALID_DL_HANDLE        Invalid handle passed
 * CSSM_TP_INVALID_DB_HANDLE        Invalid handle passed
 * CSSM_TP_SIGN_SCOPE_UNSUPPORTED   Specified signing scope is unsupported by this module
 * CSSM_FUNCTION_NOT_IMPLEMENTED    Function not implemented
 * 
 */

CSSM_DATA_PTR CSSMAPI 
CertSign(CSSM_TP_HANDLE             TPHandle,
         CSSM_CL_HANDLE             CLHandle,
         CSSM_CC_HANDLE             CCHandle,
         const CSSM_DL_DB_LIST_PTR  DBList,
         const CSSM_DATA_PTR        CertToBeSigned,
         const CSSM_CERTGROUP_PTR   SignerCertGroup,
         const CSSM_FIELD_PTR       SignScope,
         uint32                     ScopeSize)
{
   TPTRACE(jonahtp_trace_info, "CSSM_DATA_PTR CertSign(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_CC_HANDLE,CSSM_DL_DB_LIST_PTR,CSSM_DATA_PTR,CSSM_CERTGROUP_PTR,CSSM_FIELD_PTR,uint32)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: CertSign()\n");
#endif
   CSSM_ClearError();
   CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_FUNCTION_NOT_IMPLEMENTED);
   return (CSSM_DATA_PTR)NULL;
}

//------------------------------------------------------------
// function: CertRevoke
//------------------------------------------------------------
/*
 * The TP module determines whether the revoking certificate 
 * group can revoke the subject certificate group.  Once the 
 * trust is established, the TP revokes the subject certificate 
 * by adding it to the certificate revocation list. The revoker 
 * certificate is used to sign the resultant CRL.
 * 
 * Parameters
 * TPHandle (input)
 * The handle that describes the add-in trust policy module used 
 * to perform this function.
 *
 * CLHandle (input/optional)
 * The handle that describes the add-in certificate library 
 * module used to perform this function.
 * 
 * CCHandle (input/optional)
 * The handle that describes a context for cryptographic operations. 
 * The cryptographic context specifies the handle of the cryptographic 
 * service provider (CSP) that must be used to perform the operation. 
 * If no cryptographic context is specified, the TP module uses an 
 * assumed context, if required.
 * 
 * DBList (input/optional)
 * A list of certificate databases containing certificates that 
 * may be used to construct the trust structure of the subject 
 * and revoker certificate group.
 * 
 * OldCrl (input/optional)
 * A pointer to the CSSM_DATA structure containing an existing 
 * certificate revocation list.  If this input is NULL, a new list is created.
 * 
 * CertGroupToBeRevoked (input)
 * A pointer to the CSSM_CERTGROUP structure containing one or 
 * more related certificates to be revoked.
 * 
 * RevokerCertGroup (input)
 * A pointer to the CSSM_CERTGROUP structure containing the 
 * certificate used to revoke the target certificates.
 * 
 * Reason (input)
 * The reason for revoking the target certificates.
 *
 * Return Value
 * A pointer to the CSSM_DATA structure containing the updated 
 * certificate revocation list.  If the pointer is NULL, an error 
 * has occurred. This function can also return errors specific 
 * to CSP, CL and DL modules.
 * 
 * Error Codes
 * CSSM_TP_INVALID_DBLIST            Invalid DB list 
 * CSSM_TP_INVALID_CRL               Invalid CRL
 * CSSM_TP_INVALID_CERTIFICATE       Invalid certificate
 * CSSM_TP_CERTIFICATE_CANT_OPERATE  Revoker certificate can't revoke subject
 * CSSM_TP_MEMORY_ERROR              Error in allocating memory
 * CSSM_TP_CERT_REVOKE_FAIL          Unable to revoke certificate
 * CSSM_TP_INVALID_TP_HANDLE         Invalid handle
 * CSSM_TP_INVALID_CL_HANDLE         Invalid handle
 * CSSM_TP_INVALID_DL_HANDLE         Invalid handle
 * CSSM_TP_INVALID_DB_HANDLE         Invalid handle
 * CSSM_TP_INVALID_CC_HANDLE         Invalid handle
 * CSSM_FUNCTION_NOT_IMPLEMENTED     Function not implemented
 *
 */

CSSM_DATA_PTR CSSMAPI
CertRevoke(CSSM_TP_HANDLE             TPHandle, 
           CSSM_CL_HANDLE             CLHandle, 
           CSSM_CC_HANDLE             CCHandle,
           const CSSM_DL_DB_LIST_PTR  DBList,
           const CSSM_DATA_PTR        OldCrl, 
           const CSSM_CERTGROUP_PTR   CertGroupTpBeRevoked, 
           const CSSM_CERTGROUP_PTR   RevokerCertGroup, 
           CSSM_REVOKE_REASON         Reason)
{
   TPTRACE(jonahtp_trace_info, "CSSM_DATA_PTR CertRevoke(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_CC_HANDLE,CSSM_DL_DB_LIST_PTR,CSSM_DATA_PTR,CSSM_CERTGROUP_PTR,CSSM_CERTGROUP_PTR,CSSM_REVOKE_REASON)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: CertRevoke()\n");
#endif
   CSSM_ClearError();
   CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_FUNCTION_NOT_IMPLEMENTED);
   return (CSSM_DATA_PTR)NULL;
}

//------------------------------------------------------------
// function: CrlVerify
//------------------------------------------------------------
/*
 * This function verifies the integrity of the certificate 
 * revocation list and determines whether it is trusted. 
 * Some of the checks that may be performed include: 
 * verifying the signatures on the signer's certificate group, 
 * establishing the authorization of the signer to issue CRLs, 
 * verification of the signature on the CRL, verifying validity 
 * period of the CRL and the date the CRL was issued.
 * 
 * Parameters
 * TPHandle (input)
 * The handle that describes the add-in trust policy module 
 * used to perform this function.
 * 
 * CLHandle (input/optional)
 * The handle that describes the add-in certificate library 
 * module that can be used to manipulate the certificates to be verified.
 * 
 * CSPHandle (input/optional)
 * The handle referencing a cryptographic service provider to 
 * be used to verify signatures on the signer's certificate 
 * and on the CRL. The TP module is responsible for creating 
 * the cryptographic context structure required to perform 
 * the verification operation. If no CSP is specified, the 
 * TP module uses an assumed CSP to perform the operations.
 * 
 * DBList (input/optional)
 * A list of handle pairs specifying a data storage library 
 * module and a data store managed by that module. These data 
 * stores can be used to store or retrieve objects (such as 
 * certificate and CRLs) related to the signer's certificate. 
 * If no DL and DB handle pairs are specified, the TP module 
 * can use an assumed DL module and an assumed data store, 
 * if required. 
 * 
 * CrlToBeVerified (input)
 * A pointer to the CSSM_DATA structure containing a signed 
 * certificate revocation list to be verified.
 * 
 * SignerCertGroup (input)
 * A pointer to the CSSM_CERTGROUP structure containing 
 * one or more related certificates used to sign the CRL.
 * 
 * VerifyScope (input/optional)
 * A pointer to the CSSM_FIELD array indicating the CRL 
 * fields to be included in the CRL signature verification 
 * process.  A null input verifies the signature assuming 
 * the module's default set of fields were used in the 
 * signaturing process. (This can include all fields in the CRL.)
 * 
 * ScopeSize (input)
 * The number of entries in the verify scope list. If the 
 * verification scope is not specified, the input parameter 
 * value for scope size must be zero.
 * 
 * Return Value
 * A CSSM_TRUE return value means the certificate revocation 
 * list can be trusted.  If CSSM_FALSE is returned, an 
 * error has occurred. This function may return errors 
 * specific to CSP, CL and DL modules.
 * 
 * Error Codes
 * CSSM_TP_INVALID_DBLIST            Invalid DB list
 * CSSM_TP_INVALID_CERTIFICATE       Invalid certificate
 * CSSM_TP_NOT_SIGNER                Signer certificate is not signer of CRL
 * CSSM_TP_NOT_TRUSTED               Certificate revocation list can't be trusted
 * CSSM_TP_CRL_VERIFY_FAIL           Unable to verify certificate
 * CSSM_TP_INVALID_TP_HANDLE         Invalid handle
 * CSSM_TP_INVALID_CL_HANDLE         Invalid handle
 * CSSM_TP_INVALID_DL_HANDLE         Invalid handle
 * CSSM_TP_INVALID_DB_HANDLE         Invalid handle
 * CSSM_TP_VERIFY_SCOPE_UNSUPPORTED  Specified verifying scope unsupported by this module
 * CSSM_FUNCTION_NOT_IMPLEMENTED     Function not implemented
 *
 */

CSSM_BOOL CSSMAPI
CrlVerify(CSSM_TP_HANDLE             TPHandle, 
          CSSM_CL_HANDLE             CLHandle, 
          CSSM_CSP_HANDLE            CSPHandle,
          const CSSM_DL_DB_LIST_PTR  DBList,
          const CSSM_DATA_PTR        CrlToBeVerified,
          const CSSM_CERTGROUP_PTR   SignerCertGroup, 
          const CSSM_FIELD_PTR       VerifyScope,
          uint32                     ScopeSize)
{
   TPTRACE(jonahtp_trace_info, "CSSM_BOOL CrlVerify(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_CSP_HANDLE,CSSM_DL_DB_LIST_PTR,CSSM_DATA_PTR,CSSM_CERTGROUP_PTR,CSSM_FIELD_PTR,uint32)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: CrlVerify()\n");
#endif
   CSSM_ClearError();
   CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_FUNCTION_NOT_IMPLEMENTED);
   return (CSSM_FALSE);
}


//------------------------------------------------------------
// function: CrlSign
//------------------------------------------------------------
/*
 * This function signs a certificate revocation list.  The TP 
 * module determines whether the signer's certificate is trusted 
 * to sign the certificate revocation list. If trust is satisfied, 
 * then the TP module has the option to carry out the service or 
 * to return a permission status without performing the service. 
 * This allows the library to support external as well as internal 
 * CRL service models. In either model, once a CRL is signed, 
 * revocation records can no longer be added to that CRL. To do so 
 * would break the integrity of the signature resulting in a 
 * non-verifiable, rejected CRL.
 * 
 * Parameters
 * TPHandle (input)
 * The handle that describes the add-in trust policy module 
 * used to perform this function.
 * 
 * CLHandle (input/optional)
 * The handle that describes the add-in certificate library 
 * module used to perform this function.
 * 
 * CCHandle (input/optional)
 * The handle that describes a context for cryptographic operations. 
 * The cryptographic context specifies the handle of the 
 * cryptographic service provider (CSP) that must be used to 
 * perform the operation. If no cryptographic context is specified, 
 * the TP module uses an assumed context, if required.
 * 
 * DBList (input/optional)
 * A list of certificate databases containing certificates that 
 * may be used to construct the trust structure of the signer 
 * certificate group.
 * 
 * CrlToBeSigned (input)
 * A pointer to the CSSM_DATA structure containing a certificate 
 * revocation list to be signed.
 * 
 * SignerCertGroup (input)
 * A pointer to the CSSM_CERTGROUP structure containing one or 
 * more related certificates used to sign the CRL.
 * 
 * SignScope (input/optional)
 * A pointer to the CSSM_FIELD array containing the tags of 
 * the CRL fields to be included in the signing process.  
 * If the signing scope is null, the TP Module must assume a 
 * default scope (portions of the CRL to be hashed) when 
 * performing the signing process.
 * 
 * ScopeSize (input)
 * The number of entries in the sign scope list. If the signing 
 * scope is not specified, the input parameter value for scope 
 * size must be zero.
 * 
 * Return Value
 * A pointer to the CSSM_DATA structure containing the signed 
 * certificate revocation list.  If the pointer is NULL, an 
 * error has occurred. This function may return errors 
 * specific to CSP, CL and DL modules.
 * 
 * Error Codes
 * CSSM_TP_INVALID_DBLIST           Invalid DB list
 * CSSM_TP_INVALID_CERTIFICATE      Invalid certificate
 * CSSM_TP_CERTIFICATE_CANT_OPERATE Signer certificate can't sign certificate revocation list
 * CSSM_TP_MEMORY_ERROR             Error in allocating memory
 * CSSM_TP_CRL_SIGN_FAIL            Unable to sign certificate revocation list
 * CSSM_TP_INVALID_TP_HANDLE        Invalid handle
 * CSSM_TP_INVALID_CL_HANDLE        Invalid handle
 * CSSM_TP_INVALID_DL_HANDLE        Invalid handle
 * CSSM_TP_INVALID_DB_HANDLE        Invalid handle
 * CSSM_TP_SIGN_SCOPE_UNSUPPORTED   Specified signing scope is unsupported by this module
 * CSSM_FUNCTION_NOT_IMPLEMENTED    Function not implemented
 *
 */

CSSM_DATA_PTR CSSMAPI
CrlSign(CSSM_TP_HANDLE             TPHandle, 
        CSSM_CL_HANDLE             CLHandle, 
        CSSM_CC_HANDLE             CCHandle,
        const CSSM_DL_DB_LIST_PTR  DBList,
        const CSSM_DATA_PTR        CrlToBeSigned, 
        const CSSM_CERTGROUP_PTR   SignerCertGroup, 
        const CSSM_FIELD_PTR       SignScope,
        uint32                     ScopeSize)
{
   TPTRACE(jonahtp_trace_info, "CSSM_DATA_PTR CrlSign(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_CC_HANDLE,CSSM_DL_DB_LIST_PTR,CSSM_DATA_PTR,CSSM_CERTGROUP_PTR,CSSM_FIELD_PTR,uint32)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: CrlSign()\n");
#endif
   CSSM_ClearError();
   CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_FUNCTION_NOT_IMPLEMENTED);
   return (CSSM_DATA_PTR)NULL;
}

//------------------------------------------------------------
// function: ApplyCrlToDb
//------------------------------------------------------------
/*
 * This function updates persistent storage to reflect entries 
 * in the certificate revocation list. This results in designating 
 * persistent certificates as revoked.
 * 
 * Parameters
 * TPHandle (input)
 * The handle that describes the add-in trust policy module 
 * used to perform this function.
 * 
 * CLHandle (input/optional)
 * The handle that describes the add-in certificate library 
 * module that can be used to manipulate the CRL as it is 
 * applied to the data store and to manipulate the certificates 
 * effected by the CRL, if required. 
 * 
 * CSPHandle (input/optional)
 * The handle referencing a Cryptographic Service Provider 
 * to be used to verify signatures on the CRL determining 
 * whether to trust the CRL and apply it to the data store. 
 * The TP module is responsible for creating the cryptographic 
 * context structures required to perform the verification operation.
 * 
 * DBList (input/optional)
 * A list of handle pairs specifying a data storage library 
 * module and a data store managed by that module. These data 
 * stores can contain certificates that might be effected by 
 * the CRL, they may contain CRLs, or both. If no DL and DB 
 * handle pairs are specified, the TP module must use an 
 * assumed DL module and an assumed data store for this operation.
 * 
 * CrlToBeApplied(input)
 * A pointer to the CSSM_DATA structure containing a 
 * certificate revocation list to be applied to the data store.
 * 
 * Return Value
 * A CSSM_OK return value means the certificate revocation 
 * list has been used to update the revocation status of 
 * certificates in the specified database.  If CSSM_FAIL is 
 * returned, an error has occurred. This function may 
 * return errors specific to CSP, CL and DL modules.
 * 
 * Error Codes
 * CSSM_TP_INVALID_DBLIST         Invalid DB list
 * CSSM_TP_INVALID_CRL            Invalid certificate revocation list
 * CSSM_TP_NOT_TRUSTED            Certificate revocation list can't be trusted
 * CSSM_TP_APPLY_CRL_TO_DB_FAIL   Unable to apply certificate revocation list on database
 * CSSM_TP_INVALID_TP_HANDLE      Invalid handle
 * CSSM_TP_INVALID_CL_HANDLE      Invalid handle
 * CSSM_TP_INVALID_DL_HANDLE      Invalid handle
 * CSSM_TP_INVALID_DB_HANDLE      Invalid handle
 * CSSM_FUNCTION_NOT_IMPLEMENTED  Function not implemented
 *
 */

CSSM_RETURN CSSMAPI 
ApplyCrlToDb(CSSM_TP_HANDLE             TPHandle, 
             CSSM_CL_HANDLE             CLHandle, 
             CSSM_CSP_HANDLE            CSPHandle,
             const CSSM_DL_DB_LIST_PTR  DBList,
             const CSSM_DATA_PTR        Crl)
{
   TPTRACE(jonahtp_trace_info, "CSSM_RETURN ApplyCrlToDb(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_CSP_HANDLE,CSSM_DL_DB_LIST_PTR,CSSM_DATA_PTR)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: ApplyCrlToDb()\n");
#endif
   CSSM_ClearError();
   CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_FUNCTION_NOT_IMPLEMENTED);
   return (CSSM_FAIL);
}


//------------------------------------------------------------
// function: CertGroupConstruct
//------------------------------------------------------------
/*
 * This function builds a collection of certificates that 
 * together make up a meaningful credential for a given trust 
 * domain. For example, in a hierarchical trust domain, a 
 * certificate group is a chain of certificates from an end 
 * entity to a top-level certification authority. The 
 * constructed certificate group format is implementation 
 * specific. However, the subject or end-entity is always 
 * the first certificate in the group. 
 * 
 * A partially constructed certificate group is specified 
 * in CertGroupFrag. The first certificate is interpreted 
 * to be the subject or end-entity certificate. Subsequent 
 * certificates in the CertGroupFrag structure may be 
 * used during the construction of a certificate group 
 * in conjunction with certificates found in DBList. The 
 * trust policy defines the certificates that will be 
 * included in the resulting set. 
 * 
 * The constructed certificate group can be consistent 
 * locally or globally. Consistency can be limited to 
 * the local system if locally-defined anchor certificates 
 * are inserted into the group.
 * 
 * Parameters
 * TPHandle (input)
 * The handle that describes the add-in trust policy 
 * module used to perform this function.
 * 
 * CLHandle (input/optional)
 * The handle that describes the add-in certificate 
 * library module used to perform this function.
 * 
 * CSPHandle (input/optional)
 * The handle that describes the add-in cryptographic 
 * service providercertificate library module used 
 * to perform verification during group constructionthis function.
 * 
 * CertGroupFrag (input)
 * The first certificate in the group represents the 
 * target certificate for which a group of semantically 
 * related certificates will be assembled. Subsequent 
 * intermediate certificates can be supplied by the 
 * caller. They need not be in any particular order.
 * 
 * DBList (input)
 * A list of databases containing certificates that may 
 * be used to construct the trust structure of the subject certificate group.
 * 
 * Return Value
 * A CSSM_CERTGROUP_PTR which points to a valid certificate group.  
 * If the pointer returned is NULL, an error has occurred. 
 * This function may return errors specific to CL and DL modules.
 * 
 * Error Codes
 * CSSM_TP_INVALID_TP_HANDLE      Invalid handle
 * CSSM_TP_INVALID_CL_HANDLE      Invalid handle
 * CSSM_TP_INVALID_DL_HANDLE      Invalid handle
 * CSSM_TP_INVALID_DB_HANDLE      Invalid handle
 * CSSM_TP_INVALID_CERTIFICATE    Invalid certificate
 * CSSM_TP_INVALID_CERTGROUP_PTR  Invalid certificate group pointer
 * CSSM_TP_INVALID_DBLIST         Invalid DB list
 * CSSM_TP_CERTGROUP_NOT_FOUND    Unable to construct a meaningful group of certificates
 * CSSM_FUNCTION_NOT_IMPLEMENTED  Function not implemented
 *
 */

CSSM_CERTGROUP_PTR CSSMAPI 
CertGroupConstruct(CSSM_TP_HANDLE       TPHandle,
                   CSSM_CL_HANDLE       CLHandle,
                   CSSM_CSP_HANDLE      CSPHandle,
                   CSSM_CERTGROUP_PTR   CertGroupFrag,
                   CSSM_DL_DB_LIST_PTR  DBList)
{
   TPTRACE(jonahtp_trace_info, "CSSM_CERTGROUP_PTR CertGroupConstruct(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_CSP_HANDLE,CSSM_CERTGROUP_PTR,CSSM_DL_DB_LIST_PTR)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: CertGroupConstruct()\n");
#endif
   CSSM_ClearError();
   CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_FUNCTION_NOT_IMPLEMENTED);
   return (CSSM_CERTGROUP_PTR)NULL;
}


//------------------------------------------------------------
// function: CertGroupPrune
//------------------------------------------------------------

CSSM_CERTGROUP_PTR CSSMAPI 
CertGroupPrune(CSSM_TP_HANDLE       TPHandle,
               CSSM_CL_HANDLE       CLHandle,
               CSSM_CERTGROUP_PTR   OrderedCertGroup,
               CSSM_DL_DB_LIST_PTR  DBList)
{
   TPTRACE(jonahtp_trace_info, "CSSM_CERTGROUP_PTR CertGroupPrune(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_CERTGROUP_PTR,CSSM_DL_DB_LIST_PTR)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: CertGroupPrune()\n");
#endif
   CSSM_ClearError();
   CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_FUNCTION_NOT_IMPLEMENTED);
   return (CSSM_CERTGROUP_PTR)NULL;
}


//------------------------------------------------------------
// function: CertGroupVerify
//------------------------------------------------------------
/*
 * This function determines whether the subject certificate 
 * of a certificate group is trusted. The actions performed 
 * by this function differ based on the trust policy domain.
 * 
 * Anchor certificates are a list of implicitly trusted 
 * certificates. These include root certificates, cross 
 * certified certificates, and locally defined sources of trust. 
 * These certificates form the basis to determine trust in 
 * the subject certificate.
 * 
 * A policy identifier can specify an additional set of 
 * conditions that must be satisfied by the subject 
 * certificate in order to meet the trust criteria. 
 * The name space for policy identifiers is defined by 
 * the application domains to which the policy applies.  
 * A list of policy identifiers can be specified and be 
 * the stopping condition for evaluating that set of conditions.
 * 
 * The evaluation and verification process can produce a 
 * list of evidence. The evidence can be selected values 
 * from the certificates examined in the verification process, 
 * entire certificates from the process or other pertinent 
 * information that forms an audit trail of the verification 
 * process. This evidence is returned to the caller after 
 * all steps in the verification process have been completed.  
 * The caller must consult TP module documentation outside 
 * of this specification to determine the form of the 
 * evidence returned by a specific TP module.
 * 
 * If verification succeeds, the trust policy module may 
 * carry out the action on the specified data or may 
 * return approval for the action requiring the caller 
 * to perform the action.  The caller must consult TP 
 * module documentation outside of this specification 
 * to determine all module-specific side effects of this operation.
 * 
 * Parameters
 * TPHandle (input)
 * The handle that describes the add-in trust policy module 
 * used to perform this function.
 * 
 * CLHandle (input/optional)
 * The handle that describes the add-in certificate library 
 * module that can be used to manipulate the subject 
 * certificate and anchor certificates.
 * 
 * CSPHandle (input/optional)
 * The handle that describes the add-in cryptographic service 
 * provider module used to perform this function.
 * 
 * DBList (input/optional)
 * A list of certificate databases containing certificates 
 * that may be used to construct the trust structure of both 
 * the subject and signer certificate group.
 * 
 * PolicyIdentifiers (input/optional)
 * The policy identifier is an OID-value pair. The CSSM_OID 
 * structure contains the name of the policy, and the 
 * value is an optional, caller-specified input value for 
 * the TP module to use when applying the policy. 
 * 
 * NumberofPolicyIdentifiers (input)
 * The number of Policy Identifiers provided in the 
 * PolicyIdentifiers parameter.
 * 
 * VerificationAbortCondition (input/optional)
 * When a TP module verifies multiple conditions or 
 * multiple policies, the TP module can allow the caller 
 * to specify when to abort the verification process. 
 * If supported by the TP module, this selection can 
 * affect the evidence returned by the TP module to the 
 * caller. The default stopping condition is to stop 
 * evaluation according to the policy defined in 
 * the TP Module. The possible stopping conditions 
 * and their meaning are defined as follows:
 * 
 * CSSM_TP_STOP_ON         Definition
 * CSSM_STOP_ON_POLICY     Stop verification whenever 
 *                         the policy dictates it
 * CSSM_STOP_ON_NONE       Stop verification only after all 
 *                         conditions have been tested 
 *                         (ignoring the pass-fail status of each condition)
 * CSSM_STOP_ON_FIRST_PASS Stop verification on the first condition that passes
 * CSSM_STOP_ON_FIRST_FAIL Stop verification on the first condition that fails
 * 
 * The TP module may ignore the caller's specified 
 * stopping condition and revert to the default 
 * of stopping according to the policy embedded in the module.
 * 
 * SubjectCert (input)
 * A pointer to the CSSM_DATA structure containing 
 * the subject certificate. 
 * 
 * AnchorCerts (input/optional)
 * A pointer to the CSSM_DATA structure containing 
 * one or more certificates to be used to validate 
 * the subject certificate. These certificates can 
 * be root certificates, cross-certified certificates, 
 * and certificates belonging to locally 
 * designated sources of trust.
 * 
 * NumberofAnchorCerts (input)
 * The number of anchor Certificates provided in 
 * the AnchorCerts parameter.
 * 
 * VerifyScope (input/optional)
 * A pointer to the CSSM_FIELD array containing 
 * the OID/Value pairs that are to be used to 
 * qualify the validity of the Certificate.  
 * The context of the validity checks will be 
 * evident from each OID/Value pairing. If 
 * VerifyScope is not specified, the TP Module 
 * must assume a default scope (portions of 
 * the Subject certificate) when performing 
 * the verification process.
 * 
 * ScopeSize (input)
 * The number of entries in the verify scope list. 
 * If the verification scope is not specified, 
 * the input scope size must be zero.
 * 
 * Action (input/optional)
 * An application-specific and application-defined 
 * action to be performed under the authority of 
 * the input certificate. If no action is specified, 
 * the TP module defines a default action and 
 * performs verification assuming that action is 
 * being requested. [Note: it is also possible 
 * that a TP module verifies certificates for 
 * only one action.] 
 * 
 * Data (input/optional)
 * A pointer to the CSSM_DATA structure containing 
 * the application-specific data or a reference 
 * to the application-specific data upon which the 
 * requested action should be performed. If no data 
 * is specified, the TP module defines one or more 
 * default data objects upon which the action or 
 * default action would be performed.
 * 
 * Evidence (output/optional)
 * A pointer to a list of CSSM_DATA_PTR objects 
 * containing an audit trail of evidence constructed 
 * by the TP module during the verification process. 
 * Typically this is a list of Certificates and CRLs 
 * that were used to establish the validity of the 
 * Subject Certificate, but other objects may be 
 * appropriate for other types of trust policies.
 * 
 * EvidenceSize (output)
 * Pointer to the number of entries in the Evidence list. 
 * The returned value is zero if no evidence is produced. 
 * Evidence may be produced even when verification fails. 
 * This evidence can describe why and how the operation 
 * failed to verify the subject certificate.
 * 
 * Return Value
 * A CSSM_TRUE return value signifies that 
 * the certificate can be trusted.  When CSSM_FALSE 
 * is returned, either the certificate cannot be 
 * trusted or an error has occurred. This function may 
 * return errors specific to CSP, CL and DL modules.
 * 
 * Error Codes
 * CSSM_TP_INVALID_TP_HANDLE         Invalid handle
 * CSSM_TP_INVALID_CL_HANDLE         Invalid handle
 * CSSM_TP_INVALID_DL_HANDLE         Invalid handle
 * CSSM_TP_INVALID_DB_HANDLE         Invalid handle
 * CSSM_TP_INVALID_CC_HANDLE         Invalid handle
 * CSSM_TP_INVALID_DBLIST            Invalid DB list
 * CSSM_TP_INVALID_CERTGROUP_PTR     Invalid certificate group pointer
 * CSSM_TP_INVALID_STOP_ON_POLICY    Invalid verification stop policy specified
 * CSSM_TP_CERTGROUP_CONSTRUCT_FAIL  Failure to construct a complete certificate group necessary to determine trust
 * CSSM_TP_ANCHOR_NOT_FOUND          The subject certificate could not be verified to a specified anchor of trust
 * CSSM_TP_NOT_SIGNER                Signer certificate is not signer of subject
 * CSSM_TP_NOT_TRUSTED               Signature can't be trusted
 * CSSM_TP_CERT_VERIFY_FAIL          Unable to verify certificate
 * CSSM_TP_INVALID_ACTION_DATA       Invalid action data specified for action
 * CSSM_TP_VERIFY_ACTION_FAIL        Unable to determine trust for action
 * CSSM_TP_INVALID_ANCHOR            An anchor certificate could not be identified
 * CSSM_TP_VERIFY_SCOPE_UNSUPPORTED  Verify scope not supported by module
 * CSSM_TP_ANCHOR_CERTS_UNSUPPORTED  Anchor certificates not supported by module
 * CSSM_FUNCTION_NOT_IMPLEMENTED     Function not implemented
 * 
 */

CSSM_BOOL CSSMAPI 
CertGroupVerify(CSSM_TP_HANDLE            TPHandle,
                CSSM_CL_HANDLE            CLHandle,
                CSSM_DL_DB_LIST_PTR       DBList,
                CSSM_CSP_HANDLE           CSPHandle,
                const CSSM_FIELD_PTR      PolicyIdentifiers,
                uint32                    NumberofPolicyIdentifiers,
                CSSM_TP_STOP_ON           VerificationAbortOn,
                const CSSM_CERTGROUP_PTR  CertToBeVerified,
                const CSSM_DATA_PTR       AnchorCerts,
                uint32                    NumberofAnchorCerts,
                const CSSM_FIELD_PTR      VerifyScope,
                uint32                    ScopeSize,
                CSSM_TP_ACTION            Action,
                const CSSM_DATA_PTR       Data,
                CSSM_DATA_PTR*            Evidence,
                uint32*                   EvidenceSize)
{
   TPTRACE(jonahtp_trace_info, "CSSM_BOOL CertGroupVerify(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_DL_DB_LIST_PTR,CSSM_CSP_HANDLE,CSSM_FIELD_PTR,uint32,CSSM_TP_STOP_ON,CSSM_CERTGROUP_PTR,CSSM_DATA_PTR,uint32,CSSM_FIELD_PTR,uint32,CSSM_TP_ACTION,CSSM_DATA_PTR,CSSM_DATA_PTR*,uint32*)");

#ifdef _DEBUG
   printf("Jonah Trust Policy Module: CertGroupVerify()\n");
#endif

   CSSM_ClearError();

   //------------------------------------------------------------
   // validate CSSM parameters
   //------------------------------------------------------------

   if (EvidenceSize != NULL)  *EvidenceSize = 0;
   if (Evidence     != NULL)  *Evidence     = NULL;

   if ( NULL != VerifyScope || 0 != ScopeSize )
   {
      // CSSM_TP_VERIFY_SCOPE_UNSUPPORTED not defined in cssmerr.h!
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_INCOMPATIBLE_VERSION);
      return CSSM_FALSE;
   }
   if (0 == CSPHandle)
   {
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_INVALID_CC_HANDLE);
      return CSSM_FALSE;
   }
   if (0 == TPHandle) 
   {
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_INVALID_TP_HANDLE);
      return CSSM_FALSE;
   }
   if ( NULL == CertToBeVerified || CertToBeVerified->NumCerts <= 0 )
   {
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_INVALID_CERTIFICATE);
      return CSSM_FALSE;
   }
   if ( NumberofAnchorCerts > 0 && NULL == AnchorCerts )
   {
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_INVALID_CERTIFICATE);
      return CSSM_FALSE;
   }
   if ( 
          CSSM_TP_STOP_ON_POLICY != VerificationAbortOn  || 
          1 != NumberofPolicyIdentifiers                 || 
          NULL == PolicyIdentifiers                      ||
          JONAHTP_POLICY_OID_LENGTH != PolicyIdentifiers->FieldOid.Length
      )
   {
      // CSSM_TP_INVALID_STOP_ON_POLICY not defined in cssmerr.h!
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_INCOMPATIBLE_VERSION);
      return CSSM_FALSE;
   }

   if (memcmp(JonahPolicy, PolicyIdentifiers->FieldOid.Data, PolicyIdentifiers->FieldOid.Length) != 0)
   {
      // CSSM_TP_INVALID_STOP_ON_POLICY not defined in cssmerr.h!
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_INCOMPATIBLE_VERSION);
      return CSSM_FALSE;
   }

   //------------------------------------------------------------
   // Usage Notes:
   //
   // (1) We ASSUME that top of chain starts with first AnchorCert
   // (2) We ASSUME that chain is completed (from top to bottom) by 
   //     CertsToBeVerified so that last element in array is end-entity 
   //     in question.
   // (3) Future: Use Data parameter to allow user to pass in 
   //     a initialPolicySet other than ANY-POLICY?
   //
   //------------------------------------------------------------

   bool              validationFailed     = false;
   pkix_validator*   validationPtr        = 0;
   pkix_certificate* certificationPathPtr = 0;
   int               status               = 0;

   try
   {
      //------------------------------------------------------------
      // create array of pkix_certificates suitable for validation engine
      //------------------------------------------------------------

      uint32 numOfCertsInChain = CertToBeVerified->NumCerts + NumberofAnchorCerts;

      certificationPathPtr = new pkix_certificate[numOfCertsInChain];

      for (uint32 j = 0; j < NumberofAnchorCerts; j++)
      {
         r_buffer_t derBuffer;
         derBuffer.data     = AnchorCerts[j].Data;
         derBuffer.data_len = AnchorCerts[j].Length;
         if ((status = certificationPathPtr[j].read(derBuffer)) != 0)
            throw TPASNException(status);
      }
      
      for (uint32 i = 0; i < CertToBeVerified->NumCerts; i++)
      {
         r_buffer_t derBuffer;
         derBuffer.data     = CertToBeVerified->CertList[i].Data;
         derBuffer.data_len = CertToBeVerified->CertList[i].Length;
         if ((status = certificationPathPtr[i+NumberofAnchorCerts].read(derBuffer)) != 0)
            throw TPASNException(status);
      }

      //------------------------------------------------------------
      // instantiate validator
      //------------------------------------------------------------

      PolicyState initialPolicySet;
      time_t      currentTime    = time(0);
      time_t      validationTime = time(0);

      validationPtr = new pkix_validator(currentTime,
                                         validationTime,
                                         certificationPathPtr,
                                         2, 
                                         initialPolicySet, 
                                         CSPHandle,
                                         DBList);

      //------------------------------------------------------------
      // validate the chain; any errors are reported as exception
      //------------------------------------------------------------

      validationPtr->validateCertificationPath();

   }
   catch (TPASNException& error)
   {
      validationFailed = true;
      CSSM_ClearError();
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_INVALID_CERTIFICATE);
   }
   catch (TPCSSMException& error)
   {
      validationFailed = true;
//      CSSM_ClearError();
//      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_TP_CERT_VERIFY_FAIL);
   }
   catch (TPException& error)
   {
      // all internal TP error codes are mapped to the CSSM TP private error code range.
      validationFailed = true;
      CSSM_ClearError();
      CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, error._errorCode+CSSM_TP_PRIVATE_ERROR );
   }

   //------------------------------------------------------------
   // clean up any allocated memory
   //------------------------------------------------------------

   delete validationPtr;
   delete [] certificationPathPtr;

   if (validationFailed)
   {
      return CSSM_FALSE;
   }
   else
   {
      return CSSM_TRUE;
   }
}


//------------------------------------------------------------
// function: PassThrough
//------------------------------------------------------------
/*
 * This function allows clients to call Trust Policy module-specific 
 * operations that have been exported. Such operations may include 
 * queries or services specific to the domain represented by the TP module.
 * 
 * Parameters
 * TPHandle (input)
 * The handle that describes the add-in trust policy module 
 * used to perform this function.
 * 
 * CLHandle (input/optional)
 * The handle that describes the add-in certificate library 
 * module used to perform this function.
 * 
 * CSPHandle (input/optional)
 * The handle that describes the add-in cryptographic service 
 * provider module used to perform this function.
 * 
 * DBList (input/optional)
 * A list of certificate databases containing certificates that 
 * may be used by the pass-through operation.
 * 
 * PassThroughId (input)
 * An identifier assigned by the TP module to indicate the 
 * exported function to perform.
 * 
 * InputParams (input/optional)
 * A pointer to the CSSM_DATA structure containing parameters 
 * to be interpreted in a function-specific manner by the TP module. 
 * 
 * Return Value
 * A pointer to the CSSM_DATA structure containing the output 
 * from the pass-through function.  The output data must be 
 * interpreted by the calling application based on externally-defined 
 * information provided by the trust policy module vendor.  
 * If the pointer is NULL, an error has occurred. This function can 
 * also return errors specific to CSP, CL and DL modules.
 * 
 * Error Codes
 * CSSM_TP_INVALID_TP_HANDLE      Invalid handle
 * CSSM_TP_INVALID_CL_HANDLE      Invalid handle
 * CSSM_TP_INVALID_DL_HANDLE      Invalid handle
 * CSSM_TP_INVALID_DB_HANDLE      Invalid handle
 * CSSM_TP_INVALID_CSP_HANDLE     Invalid handle
 * CSSM_TP_INVALID_DATA_POINTER   Invalid pointer for input data
 * CSSM_TP_INVALID_ID             Invalid pass-through ID
 * CSSM_TP_MEMORY_ERROR           Error in allocating memory
 * CSSM_TP_PASS_THROUGH_FAIL      Unable to perform passthrough
 * CSSM_FUNCTION_NOT_IMPLEMENTED  Function not implemented
 *
 */

CSSM_DATA_PTR CSSMAPI 
PassThrough(CSSM_TP_HANDLE  TPHandle, 
            CSSM_CL_HANDLE  CLHandle, 
            CSSM_DL_HANDLE  DLHandle, 
            CSSM_DB_HANDLE  DBHandle, 
            CSSM_CC_HANDLE  CCHandle, 
            uint32          PassThroughId,
            const void*     InputParams)
{
   TPTRACE(jonahtp_trace_info, "CSSM_DATA_PTR PassThrough(CSSM_TP_HANDLE,CSSM_CL_HANDLE,CSSM_DL_HANDLE,CSSM_DB_HANDLE,CSSM_CC_HANDLE,uint32,void*)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: PassThrough()\n");
#endif
   CSSM_ClearError();

   CSSM_SetError((CSSM_GUID*)&JONAHTP_GUID, CSSM_FUNCTION_NOT_IMPLEMENTED);
   return (CSSM_DATA_PTR)NULL;
}


// Registration Info Functions

//------------------------------------------------------------
// function: Initialize
//------------------------------------------------------------

CSSM_RETURN CSSMAPI 
Initialize(CSSM_MODULE_HANDLE  ModuleHandle,
           uint32              VerMajor,
           uint32              VerMinor)
{
   TPTRACE(jonahtp_trace_info, "CSSM_RETURN Initialize(CSSM_MODULE_HANDLE,uint32,uint32)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: Initialize()\n");
#endif
   CSSM_ClearError();

   if ((VerMajor == JONAHTP_MAJOR_VERSION) && (VerMinor == JONAHTP_MINOR_VERSION) )
      return (CSSM_OK);

   return (CSSM_FAIL);
}


//------------------------------------------------------------
// function: Terminate
//------------------------------------------------------------

CSSM_RETURN CSSMAPI 
Terminate(CSSM_MODULE_HANDLE  ModuleHandle)
{
   TPTRACE(jonahtp_trace_info, "CSSM_RETURN Terminate(CSSM_MODULE_HANDLE)");
#ifdef _DEBUG
   printf("Jonah Trust Policy Module: Terminate()\n");
#endif
   CSSM_ClearError();

   return (CSSM_OK);
}


//------------------------------------------------------------
// function: EventNotify
//------------------------------------------------------------

// Not supported registration function:
// CSSM_RETURN CSSMAPI 
// EventNotify(CSSM_MODULE_HANDLE     Handle,
//             const CSSM_EVENT_TYPE  Event,
//             const uint32           Param) 
//{
//   TPTRACE(jonahtp_trace_info, "CSSM_RETURN EventNotify(CSSM_MODULE_HANDLE,CSSM_EVENT_TYPE,uint32)");
//#ifdef _DEBUG
//   printf("Jonah Trust Policy Module: EventNotify()\n");
//#endif
//}


//------------------------------------------------------------
// function: GetModuleInfo
//------------------------------------------------------------

// Not supported registration function:
// CSSM_MODULE_INFO_PTR CSSMAPI 
// GetModuleInfo(CSSM_MODULE_HANDLE  ModuleHandle,
//               CSSM_SERVICE_MASK   ServiceMask,
//               uint32              SubserviceID,
//               CSSM_INFO_LEVEL     InfoLevel)
//{
//   TPTRACE(jonahtp_trace_info, "CSSM_RETURN GetModuleInfo(CSSM_MODULE_HANDLE,CSSM_SERVICE_MASK,uint32,CSSM_INFO_LEVEL)");
//#ifdef _DEBUG
//   printf("Jonah Trust Policy Module: GetModuleInfo()\n");
//#endif
//}


//------------------------------------------------------------
// function: FreeModuleInfo
//------------------------------------------------------------

// CSSM_RETURN CSSMAPI 
// FreeModuleInfo(CSSM_MODULE_HANDLE    ModuleHandle,  
//                CSSM_MODULE_INFO_PTR  ModuleInfo)
//   TPTRACE(jonahtp_trace_info, "CSSM_RETURN FreeModuleInfo(CSSM_MODULE_HANDLE,CSSM_MODULE_INFO_PTR)");
//#ifdef _DEBUG
//   printf("Jonah Trust Policy Module: FreeModuleInfo()\n");
//#endif
//}


// Library Initialization

//------------------------------------------------------------
// function: DllMain
//------------------------------------------------------------

BOOL WINAPI
DllMain(HANDLE  hInstance, 
        DWORD   dwReason, 
        LPVOID  lpReserved)
{
   BOOL           returnValue = TRUE;
   CSSM_RETURN    rc          = CSSM_OK;      
   
   switch (dwReason) 
   {
   case DLL_PROCESS_ATTACH: 
      CSSM_ClearError();

#ifdef DEBUG
      printf("JONAHTP: Process Attaching\n");
#endif
      CSSM_SPI_TP_FUNCS tp_jmp_tbl;
      memset(&tp_jmp_tbl, 0, sizeof(tp_jmp_tbl));
      tp_jmp_tbl.CertSign                 = CertSign;
      tp_jmp_tbl.CertRevoke               = CertRevoke;
      tp_jmp_tbl.CrlVerify                = CrlVerify;
      tp_jmp_tbl.CrlSign                  = CrlSign;
      tp_jmp_tbl.ApplyCrlToDb             = ApplyCrlToDb;
      tp_jmp_tbl.CertGroupConstruct       = CertGroupConstruct;
      tp_jmp_tbl.CertGroupPrune           = CertGroupPrune;
      tp_jmp_tbl.CertGroupVerify          = CertGroupVerify;
      tp_jmp_tbl.PassThrough              = PassThrough;
      
      CSSM_MODULE_FUNCS tp_module_funcs;
      memset(&tp_module_funcs, 0, sizeof(tp_module_funcs));
      tp_module_funcs.ServiceType         = CSSM_SERVICE_TP;
      tp_module_funcs.TpFuncs             = &tp_jmp_tbl;

      CSSM_REGISTRATION_INFO tp_reg_info;
      memset(&tp_reg_info, 0, sizeof(tp_reg_info));
      tp_reg_info.Initialize              = Initialize;
      tp_reg_info.Terminate               = Terminate;
      tp_reg_info.EventNotify             = NULL;
      tp_reg_info.GetModuleInfo           = NULL;
      tp_reg_info.FreeModuleInfo          = NULL;
      tp_reg_info.ThreadSafe              = TRUE;   // yes, we're thread-safe
      tp_reg_info.ServiceSummary          = CSSM_SERVICE_TP;
      tp_reg_info.NumberOfServiceTables   = 1;
      tp_reg_info.Services                = &tp_module_funcs;
      
      // register its services with the CSSM 
      
      rc = CSSM_RegisterServices((CSSM_GUID*)&JONAHTP_GUID, 
                                 &tp_reg_info, 
                                 &UpcallTable, 
                                 NULL);
      
      if(rc != CSSM_OK)
      {
          returnValue = FALSE;
      }

      //------------------------------------------------------------
      // Read user preferences for TP behavior from INI file
      //------------------------------------------------------------

      if (!IniReadBoolean("TP","UseCRLs",_iniUseCRLs, false))
          returnValue = FALSE;
      if (!IniReadBoolean("TP","AllowExpiredCRLs",_iniAllowExpiredCRLs, true))
          returnValue = FALSE;

      break;
   case DLL_THREAD_ATTACH:
      CSSM_ClearError ();
      break;
   case DLL_THREAD_DETACH:
      CSSM_ClearError ();
      break;
   case DLL_PROCESS_DETACH:
#ifdef DEBUG
      printf("JONAHTP: Process detaching\n");
#endif   
      rc = CSSM_DeregisterServices((CSSM_GUID*)&JONAHTP_GUID);
      break;
   }
   
   return TRUE;
}


#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

//------------------------------------------------------------
// function: _init
//------------------------------------------------------------

#ifdef AIX
#include "pkixtp_rc.h"    // for version info

BOOL _init()
{
   return (DllMain(NULL, DLL_PROCESS_ATTACH, NULL));
}


//------------------------------------------------------------
// function: _fini
//------------------------------------------------------------

BOOL _fini()
{
   return (DllMain(NULL, DLL_PROCESS_DETACH, NULL));
}

#endif   // AIX

   
#ifdef __cplusplus
}
#endif // __cplusplus
