Code sample of the PKITP program (pkitpsamp.c)
Note: The following listing might not be identical to the code
sample shipped with the product. For the most current sample, see
the /usr/lpp/pkiserv/samples directory.
/*********************************************************************/
/* This file contains sample code. IBM provides this code on an */
/* 'as is' basis without warranty of any kind, either express or */
/* implied, including but not limited to, the implied warranties */
/* of merchantability or fitness for a particular purpose. */
/*********************************************************************/
/*********************************************************************/
/* */
/* Licensed Materials - Property of IBM */
/* 5694-A01 */
/* (C) Copyright IBM Corp. 2001, 2005 */
/* Status = HKY7720 */
/* */
/*********************************************************************/
/* Sample use of IBM PKITP program */
/* */
/* Purpose: Program attaches needed CSSM modules, then prompts */
/* the user for filename(s) containing DER encoded */
/* certificates. The certificate(s) are read from the */
/* file, then passed to PKITP for verification. */
/* A summary of the results are printed to stdout. */
/* */
/* Caution: In order to run this sample program, modification MUST */
/* BE MADE to several values assigned to the following */
/* variables that are defined between the block comment */
/* containing the text "Start of application specific */
/* options" and the block comment containing the text */
/* "End of application specific options"(without the */
/* quotation marks): */
/* */
/* #define NUM_LDAPS 1 */
/* Define the number of LDAP servers that PKITP should */
/* query for certificates, CRLs and ARLs. This can be 0, */
/* if entire certificate chain will be passed as input to */
/* PKITP AND caller requests to NOT process CRLs/ARLs (see */
/* useCRLs option below). */
/* */
/* struct ldap_info ldapserver[NUM_LDAPS] = */
/* { "@LDAPSERVERNAME:PORTNUMBER@", */
/* "@LDAPUSER@", */
/* "@LDAPUSERPASSWORD@"}; */
/* If NUM_LDAPS > 0, then ldapserver array should define */
/* the LDAP server:port, user and password for each LDAP */
/* server. Replace @LDAPSERVERNAME:PORTNUMBER@ with the */
/* appropriate ldap server name and port number (e.g */
/* myldap.mycompany.com:389 ). Replace @LDAPUSER@ with the */
/* appropriate ldap admin user name (e.g cn=root) and */
/* @LDAPUSERPASSWORD@ with the password for the specified */
/* ldap user name (e.g rootpw) */
/* */
/* char keyring[] = "@USERID@/@KEYRINGNAME@"; */
/* Define the SAF keyring containing trusted CA and/or */
/* site certificates. Format is "USERID/keyname". Replace */
/* @USERID@ with the userid of the keyring owner and */
/* @KEYRINGNAME@ with the name of the keyring. (e.g */
/* IBMUSER/CAring) Note that the userid and the keyring */
/* names are case sensitive so the userid is all */
/* uppercase and the keyring name is mixed case in this */
/* example. */
/* */
/* #define USECRLS 1 */
/* Define how the useCRLs option should be set. */
/* Set to 0 if no CRL processing is to be performed */
/* Set to 1, if LDAP is to be queried for CRLs and */
/* process the CRLs found. */
/* Set to 2, for strong CRL checking (With strong CRL */
/* checking, a valid CRL must be found for each CA */
/* certificate in the chain.) */
/* */
/* #define NUM_POLICIES 2 */
/* static unsigned char my_policy1[5] = */
/* {0x06,0x03,0x2a,0x03,0x04}; // DER encoded 2.3.4 */
/* static unsigned char my_policy2[7] = */
/* {0x06,0x05,0x2a,0x03,0x03,0x02,0x01}; // DER 2.3.3.2.1 */
/* CSSM_DATA policydata[NUM_POLICIES] = */
/* {{sizeof(my_policy1),(unsigned char *)my_policy1}, */
/* {sizeof(my_policy2),(unsigned char *)my_policy2}}; */
/* Define the policies that the application calling PKITP */
/* uses. These become important if a certificate in the */
/* certificate chain has a critically marked policy */
/* extension. At least one policy that is listed in such */
/* a critically marked policy extension, must appear in */
/* the list defined here or PKITP will return certificate */
/* policy error. */
/* */
/* #define INITIALExplicitPolicy FALSE */
/* Set to true if you want PKITP to require that all */
/* certificates in chain to have at least one policy */
/* listed by the policydata defined above. */
/* */
/*********************************************************************/
/* */
/*Change-Activity: */
/* $D0=MG00545, HKY7708, 020306, BRW: Initialize @D0A*/
/* TP_EVIDENCE fields for printEvidence @D0A*/
/* */
/* $D1=MG00547, HKY7708, 020306, BRW: Change to allow compile @D1A*/
/* if NUM_LDAPS or NUM_POLICIES is zero @D1A*/
/* $D2=MG01368, HKY7708, 021030, BRW: Delete attaching of CSP @D2A*/
/* $D3=MG04177, HKY7720, 040614, TCG: Fix memory/init errors @D3A*/
/*********************************************************************/
#pragma runopts("XPLINK(ON)")
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cssm.h>
#include <ibmocepdl.h>
#include <ibmswcsp.h>
#include <cssmapi.h>
#include <cssmtype.h>
#include <pkitp.h>
#include <ldapdl.h>
struct ldap_info
{
char * ldapserver;
char * ldapauthuser;
char * ldapauthpass;
};
//------------------------------------------------------------
// storage function definitions needed to talk to CSSM
//------------------------------------------------------------
#ifdef __cplusplus
extern "C"
#endif
void * OurMalloc(size_t size, void * allocRef)
{
return malloc(size);
}
#ifdef __cplusplus
extern "C"
#endif
void OurFree(void* memPtr, void * allocRef)
{
free(memPtr);
}
#ifdef __cplusplus
extern "C"
#endif
void * OurRealloc(void * memPtr,
size_t size,
void * allocRef)
{
return realloc(memPtr, size);
}
#ifdef __cplusplus
extern "C"
#endif
void * OurCalloc(size_t num,
size_t size,
void* allocRef)
{
return calloc(num, size);
}
static CSSM_API_MEMORY_FUNCS memoryFuncs; // used to pass function addresses to CSSM
//------------------------------------------------------------
// internal function declarations
//------------------------------------------------------------
int connectTP(char * ringname,
int number_ldap,
CSSM_DL_DB_LIST *,
CSSM_TP_HANDLE *); //@D1C
void disconnectTP(CSSM_DL_DB_LIST *, CSSM_TP_HANDLE);
int buildCertGroup(CSSM_CERTGROUP *, char * [], uint32);
void verifyCertGroup(CSSM_CERTGROUP certgroup,
CSSM_DL_DB_LIST * datasources_ptr,
CSSM_TP_HANDLE tphandle);
void
reportCertGroupVerify
(TP_VERIFY_EXTRA extraVerifyInfo);
void printEvidence(TP_EVIDENCE_PTR evidence_ptr);
void freeCertGroup(CSSM_CERTGROUP * certGroupPtr);
///////////////////////////////////////////////////////////////////////////
//
// Start of application specific options
//
// The defines and declarations that follow should be altered to fit the
// particular application calling PKITP.
//
///////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Define the number of LDAP servers that PKITP should query for certificates,
// CRLs and ARLs. This can be 0, if entire certificate chain will be passed as
// input to PKITP AND caller requests to NOT process CRLs/ARLs (see useCRLs
// option below).
//
// If NUM_LDAPS > 0, then ldapserver array should define the LDAP server:port,
// user and password for each LDAP server, as this example shows.
/////////////////////////////////////////////////////////////////////////////
#define NUM_LDAPS 1
#if NUM_LDAPS != 0 //@D1A
struct ldap_info ldapserver[NUM_LDAPS] =
{ "@LDAPSERVERNAME:PORTNUMBER@", // LDAP server:port
"@LDAPUSER@", // user
"@LDAPUSERPASSWORD@"}; // password
#endif //@D1A
/////////////////////////////////////////////////////////////////////////////
// Define the SAF keyring containing trusted CA and/or site certificates.
// Format is "USERID/keyname"
/////////////////////////////////////////////////////////////////////////////
char keyring[] = "@USERID@/@KEYRINGNAME@";
/////////////////////////////////////////////////////////////////////////////
// Define how the useCRLs option should be set.
// Set to 0 if no CRL processing to be done
// Set to 1, if we are to query LDAP for CRLs and process those found
// Set to 2, for strong CRL checking -- must find CRLs in LDAP.
/////////////////////////////////////////////////////////////////////////////
#define USECRLS 1
/////////////////////////////////////////////////////////////////////////////
// Define the policies that the application calling PKITP uses.
//
// These become important if a certificate in the certificate chain has a
// critically marked policy extension. At least one policy
// that is listed in such a critically marked policy extension, must appear
// in the list defined here or PKITP will return certificate policy error.
/////////////////////////////////////////////////////////////////////////////
#define NUM_POLICIES 2
#if NUM_POLICIES != 0 //@D1A
static unsigned char my_policy1[5] = {0x06,0x03,0x2a,0x03,0x04}; // DER encoded 2.3.4
static unsigned char my_policy2[7] = {0x06,0x05,0x2a,0x03,0x03,0x02,0x01}; // DER 2.3.3.2.1
CSSM_DATA policydata[NUM_POLICIES] = {{sizeof(my_policy1),(unsigned char *)my_policy1},
{sizeof(my_policy2),(unsigned char *)my_policy2}};
#endif //@D1A
#define INITIALExplicitPolicy FALSE // Set to true if you want PKITP to require that all
// certificates in chain have at least one policy
// listed by our policydata defined above
///////////////////////////////////////////////////////////////////////////
//
// End of application specific options
//
///////////////////// /////////////////////////////////////////////////////
//------------------------------------------------------------
// main
//------------------------------------------------------------
int
main(int argc, char* argv[])
{
CSSM_DL_DB_LIST datasources;
CSSM_TP_HANDLE tphandle = 0;
CSSM_CERTGROUP certGroup;
int repeating = 1;
char buffer[1024];
int num_certs = 0;
char * cert_files[25];
char * next_file;
char * input;
int rc;
rc = connectTP(keyring,NUM_LDAPS, &datasources, &tphandle); //@D1C
if (rc == 0)
{
////////////////////////////////////////////////////////////////////////////
// prompt for certificates to verify
///////////////////////////////////////////////////////////////////////////
do
{
num_certs = 0;
printf("Enter filename(s) of certificate(s). (List EE first). ");
printf("Blank line to quit.\n");
if ((input = gets(buffer)) != NULL) // get input line
{
next_file = strtok(input," ");
while ((next_file != NULL) && (num_certs < 25)) // tokenize it
{
cert_files[num_certs] = next_file;
num_certs++;
next_file = strtok(NULL," ");
}
}
////////////////////////////////////////////////////////////////////
// If we were given a list of files containing certificates, input them to TP
/////////////////////////////////////////////////////////////////////
if (num_certs > 0)
{
rc = buildCertGroup(&certGroup, cert_files, num_certs);
if (rc == 0)
{
verifyCertGroup(certGroup, &datasources, tphandle);
freeCertGroup(&certGroup);
}
}
} while (num_certs > 0);
}
disconnectTP(&datasources, tphandle);
}
//------------------------------------------------------------
// connectTP
//
// Purpose: connect to the datasources PKITP needs
// then connect to the PKITP
//
// Input: ringname - string containing "USERID/ringname" of SAF
// keyring containing trusted CA and/or SITE certificates
// number_ldap - number of ldap servers
// ldapserver - array of ldap_info structures
//
// Output: The CSSM_DL_DB_LIST structure addressed by datasources will have
// been initialized with the various handles that CSSM_ModuleAttach
// and CSSM_DL_DbOpen calls have returned
// The CSSM_TP_HANDLE addressed by tphandle_ptr will have been initialied.
// int returned will be 0 if successful, -1 if not successful.
//------------------------------------------------------------
int connectTP(char * ringname,
int number_ldap,
CSSM_DL_DB_LIST * datasources_ptr,
CSSM_TP_HANDLE * tphandle_ptr) //@D1C
{
uint32 status = 0;
int z;
CSSM_VERSION cssm_version = {CSSM_MAJOR, CSSM_MINOR};
CSSM_DB_ACCESS_TYPE access = { CSSM_TRUE,
CSSM_FALSE,
CSSM_FALSE,
CSSM_FALSE};
CSSM_VERSION DL_version;
CSSM_DL_HANDLE LDAP_dlhandle;
CSSM_MODULE_INFO* moduleInfoPtr;
void * voidptr;
CSSM_DB_ACCESS_TYPE accessRequest = { CSSM_TRUE, // ReadAccess
CSSM_TRUE, // WriteAccess
CSSM_FALSE, // PrivilegedMode
CSSM_FALSE }; // Asynchronous
memoryFuncs.malloc_func = OurMalloc;
memoryFuncs.free_func = OurFree;
memoryFuncs.realloc_func = OurRealloc;
memoryFuncs.calloc_func = OurCalloc;
memoryFuncs.AllocRef = NULL;
DL_version.Major = IBMOCEPDL_MAJOR_VERSION;
DL_version.Minor = IBMOCEPDL_MINOR_VERSION;
datasources_ptr->NumHandles = number_ldap + 1;
voidptr = malloc(sizeof(CSSM_DL_DB_HANDLE)*(number_ldap +1)); // get storage for DBlist
if (voidptr == NULL) { // @D3A
printf("connectTP unable to obtain memory: line %d\n",__LINE__); // @D3A
return -1; // @D3A
} // @D3A
memset(voidptr,0,(sizeof(CSSM_DL_DB_HANDLE)*(number_ldap +1))); // zero it
datasources_ptr->DLDBHandle = (CSSM_DL_DB_HANDLE *)voidptr;
if (CSSM_Init(&cssm_version, &memoryFuncs, NULL) != CSSM_OK)
{
printf("Failed CSSM_Init: %d, line %d\n",CSSM_GetError()->error,__LINE__);
return -1;
}
/////////////////////////////////////////////////////////////////////////////////
// attach to LDAP and open each LDAP DB
/////////////////////////////////////////////////////////////////////////////////
#if NUM_LDAPS != 0 //@D1A
if (number_ldap > 0) // if we have any LDAP sources
{
moduleInfoPtr = CSSM_GetModuleInfo((CSSM_GUID*)&LDAPDL_GUID,
CSSM_SERVICE_DL,
CSSM_ALL_SUBSERVICES,
CSSM_INFO_LEVEL_ALL_ATTR);
if (!moduleInfoPtr)
{
printf("Failed CSSM_GetModduleInfo: %d, line %d\n",CSSM_GetError()->error,__LINE__);
return -1;
}
LDAP_dlhandle = CSSM_ModuleAttach((CSSM_GUID*)&LDAPDL_GUID,
&moduleInfoPtr->Version,
&memoryFuncs,
0,
0,
0,
NULL,
NULL);
if (!LDAP_dlhandle)
{
printf("Failed CSSM_ModuleAttach: %d, line %d\n",CSSM_GetError()->error,__LINE__);
return -1;
}
// connect to multiple database instances
//------------------------------------------------------------
// fill in LDAP DL authentication information:
// necessary only if user is supplying a name and password
//------------------------------------------------------------
for (z = 0; z < number_ldap; z++) // for each LDAP source
{
LDAP_BIND_PARMS bindParms;
CSSM_USER_AUTHENTICATION userAuthentication = {0,0};
CSSM_DATA userCredential = {0,0};
CSSM_USER_AUTHENTICATION_PTR userAuthenticationPtr = 0;
datasources_ptr->DLDBHandle[z].DLHandle = LDAP_dlhandle;
if (ldapserver[z].ldapauthuser && ldapserver[z].ldapauthpass) //@D1C
{
//------------------------------------------------------------
// fill in LDAP DL specific data structure: LDAP_BIND_PARMS
//------------------------------------------------------------
bindParms.DN = ldapserver[z].ldapauthuser; //@D1C
bindParms.SASL = 0;
bindParms.credentials.Data = (uint8 *)ldapserver[z].ldapauthpass; //@D1C
bindParms.credentials.Length = strlen(ldapserver[z].ldapauthpass)+1; //@D1C
userCredential.Length = sizeof(LDAP_BIND_PARMS);
userCredential.Data = (unsigned char*)&bindParms
userAuthentication.Credential = &userCredential
userAuthenticationPtr = &userAuthentication
}
//------------------------------------------------------------
// Open LDAP DL Database
//------------------------------------------------------------
datasources_ptr->DLDBHandle[z].DBHandle = CSSM_DL_DbOpen(LDAP_dlhandle,
ldapserver[z].ldapserver, //@D1C
&accessRequest,
userAuthenticationPtr,
(void *)0);
if (!datasources_ptr->DLDBHandle[z].DBHandle)
{
printf("Failed CSSM_DL_DbOpen %d, line %d\n", CSSM_GetError()->error,__LINE__);
return -1;
}
} // end of for each each LDAP source
if (CSSM_FreeModuleInfo(moduleInfoPtr) == CSSM_FAIL)
{
printf("Failed CSSM_FreeModuleInfo, line %d, error %d\n",__LINE__,
CSSM_GetError()->error);
// This is not a catastrophic error, we'll continue
}
} // end if we have any LDAP sources
#endif //@D1A
/////////////////////////////////////////////////////////////////////////
// Attach to OCEP DL (to access RACF keyring)
///////////////////////////////////////////////////////////////////////
datasources_ptr->DLDBHandle[number_ldap].DLHandle =
CSSM_ModuleAttach(&IBMOCEPDL_GUID,
&DL_version,
&memoryFuncs,
0,
0,
0,
NULL,
NULL);
if (!(datasources_ptr->DLDBHandle[number_ldap].DLHandle))
{
printf("Failed CSSM_ModuleAttach: %d, line %d\n",CSSM_GetError()->error,__LINE__);
return -1;
}
datasources_ptr->DLDBHandle[number_ldap].DBHandle =
CSSM_DL_DbOpen(datasources_ptr->DLDBHandle[number_ldap].DLHandle,
ringname,
&access,
NULL,
NULL);
if (!(datasources_ptr->DLDBHandle[number_ldap].DBHandle))
{
printf("Failed CSSM_DL_DbOpen %d, line %d\n", CSSM_GetError()->error,__LINE__);
return -1;
}
///////////////////////////////////////////////////////////////////////
// Attach to PKITP
///////////////////////////////////////////////////////////////////////
moduleInfoPtr = CSSM_GetModuleInfo((CSSM_GUID*)&PKITP_GUID,
CSSM_SERVICE_TP,
CSSM_ALL_SUBSERVICES,
CSSM_INFO_LEVEL_ALL_ATTR);
if (!moduleInfoPtr)
{
printf("Failed CSSM_GetModduleInfo: %d, line %d\n",CSSM_GetError()->error,__LINE__);
return -1;
}
*(tphandle_ptr) = CSSM_ModuleAttach((CSSM_GUID*)&PKITP_GUID,
&moduleInfoPtr->Version,
&memoryFuncs,
0,
0,
0,
NULL,
NULL);
if (!(*tphandle_ptr))
{
printf("Failed CSSM_ModuleAttach: %d, line %d\n",CSSM_GetError()->error,__LINE__);
return -1;
}
if (CSSM_FreeModuleInfo(moduleInfoPtr) == CSSM_FAIL)
{
printf("Failed CSSM_FreeModuleInfo, line %d, error %d\n",__LINE__,
CSSM_GetError()->error);
// This is not a catastrophic error, we'll continue
}
return 0;
}
//------------------------------------------------------------
// disconnectTP
//
// Purpose: to close any open databases and detach any CSSM modules
// that connectTP attached
//
// Input: The CSSM_DL_DB_LIST structure, CSSM_TP_HANDLE,
// that were initialized by connectTP.
//
// Output: None
//------------------------------------------------------------
void disconnectTP(CSSM_DL_DB_LIST * datasources_ptr, CSSM_TP_HANDLE tphandle)
{
int x;
int status;
/////////////////////////////////////////////////////////////////
// Sever ties to LDAP
// For each LDAP database opened -- call CSSM_DL_DbClose
/////////////////////////////////////////////////////////////////
#if NUM_LDAPS != 0 //@D1A
for (x = 0; x < datasources_ptr->NumHandles - 1; x++)
{
// we close each ldap database separately
if (datasources_ptr->DLDBHandle[x].DBHandle) // if we opened database
{
status = CSSM_DL_DbClose(datasources_ptr->DLDBHandle[x]);
if (status != 0)
{
printf("Failed CSSM_DL_DbClose %d, line %d\n", CSSM_GetError()->error,__LINE__);
// we continue trying to close other stuff
}
}
}
/////////////////////////////////////////////////////////////////
// Now detach the LDAP module
/////////////////////////////////////////////////////////////////
if (datasources_ptr->DLDBHandle[0].DLHandle)
{
if ((status = CSSM_ModuleDetach(datasources_ptr->DLDBHandle[0].DLHandle)) != 0)
{
printf("Failed CSSM_ModuleDetach: %d, line %d\n", CSSM_GetError()->error,__LINE__);
// we continue trying to close other stuff
}
datasources_ptr->DLDBHandle[0].DLHandle = 0; // clear handle
}
#endif //@D1A
/////////////////////////////////////////////////////////////////
// Say goodbye to OCEP
/////////////////////////////////////////////////////////////////
status = CSSM_DL_DbClose(datasources_ptr->DLDBHandle[datasources_ptr->NumHandles - 1]);
if (status != 0)
{
printf("Failed CSSM_DL_DbClose %d, line %d\n", CSSM_GetError()->error,__LINE__);
// we continue trying to close other stuff
}
if (datasources_ptr->DLDBHandle[datasources_ptr->NumHandles - 1].DLHandle)
{
if ((status = CSSM_ModuleDetach(datasources_ptr->DLDBHandle[datasources_ptr->NumHandles - 1].DLHandle)) != 0)
{
printf("Failed CSSM_ModuleDetach: %d, line %d\n", CSSM_GetError()->error,__LINE__);
// we continue trying to close other stuff
}
datasources_ptr->DLDBHandle[datasources_ptr->NumHandles - 1].DLHandle = 0;
}
/////////////////////////////////////////////////////////////////
// Farewell PKITP
/////////////////////////////////////////////////////////////////
if (tphandle)
{
if ((status = CSSM_ModuleDetach(tphandle)) != 0)
{
printf("Failed CSSM_ModuleDetach: %d, line %d\n", CSSM_GetError()->error,__LINE__);
// we continue trying to close other stuff
}
}
return;
}
/*********************************************************************
* name: buildCertGroup - read certificates from files, set up
* CSSM_CERTGROUP to reference input certificates
*
* input: CSSM_CERTGROUP * -- addresses unintialized CSSM_CERTGROUP
* certFile - array of strings containing names of files that
* have DER encoded certificates to be verified by PKITP
* certCount - number of elements (strings) in certFile
*
* output: returns CSSM_OK if all certificates read
* - CSSM_CERTGROUP will have NumCerts set and CertList
* will be the address of array of certificates
* returns CSSM_FALSE if error reading a file
*********************************************************************/
int buildCertGroup(CSSM_CERTGROUP * certGroupPtr,
char * certFile[], uint32 certCount)
{
FILE * inFile;
CSSM_DATA * certArray = (CSSM_DATA *) calloc(certCount,sizeof(CSSM_DATA));
uint32 i, certSize;
if (certArray == NULL) // If calloc failed, exit now
return(CSSM_FAIL); // @D3A
certGroupPtr->NumCerts = certCount;
certGroupPtr->CertList = certArray;
for (i=0; i < certCount; i++) {
inFile = fopen(certFile[i],"rb");
if (!inFile) {
printf("File %s could not be opened\n",certFile[i]);
if (i > 1) // if we've read any certs before this
{
certGroupPtr->NumCerts = i - 1; // indicate how many read
freeCertGroup(certGroupPtr); // free alloc'd storage
}
return(CSSM_FAIL);
}
/* Find size of certificate file */
fseek(inFile,0L,SEEK_END);
certSize = ftell(inFile);
rewind(inFile);
/* Read in certificate data*/
certArray[i].Length = certSize;
certArray[i].Data = (uint8 *)calloc(certSize, sizeof(char));
if (certArray[i].Data == NULL) { // If calloc failed @D3A
if (i > 1) // if we've read any certs before this @D3A
{ // @D3A
certGroupPtr->NumCerts = i - 1; // indicate how many read @D3A
freeCertGroup(certGroupPtr); // free alloc'd storage @D3A
} // @D3A
return(CSSM_FAIL); // @D3A
} // @D3A
fread(certArray[i].Data, 1, certSize, inFile);
fclose(inFile);
}
return(CSSM_OK);
}
/*********************************************************************
* name: verifyCertGroup - call the Trust Policy (FINALLY)
*
* purpose: call CSSM_TP_PassThrough (PKITP) to verify certificate(s)
* call reportCertGroupVerify (internal routine to display
* results to stdout
* call CSSM_TP_PassThrough (PKITP) to free storage related to
* results
*
* input: CSSM_CERTGROUP containing number of and array of certificates
* CSSM_DL_DB_LIST containing CSSM handles for LDAP and OCEP
* CSSM_TP_HANDLE CSSM handle for PKITP
*
* output: none
*
*********************************************************************/
void verifyCertGroup(CSSM_CERTGROUP certgroup,
CSSM_DL_DB_LIST * datasources_ptr,
CSSM_TP_HANDLE tphandle)
{
/////////////////////////////////////////////////////////////////////
//
// While there are only 3 parameters on CSSM_TP_PassThrough call to PKITP:
// - the CSSM_TP_HANDLE,
// - the function code "TP_VERIFY_PASSTHROUGH" and
// - a pointer to the TP_VERIFY_EXTRA structure.
// TP_VERIFY_EXTRA structure contains many parameters, including the address of
// TP_INITIALPOLICY structure that can be used to override the default
// policy settings and the address of TP_VERIFY_EXTRA which PKITP can use
// to pass back more detailed results.
//////////////////////////////////////////////////////////////////////
TP_INITIALPOLICY initialPolicyPreferences;
TP_EVIDENCE pkixEvidence;
TP_VERIFY_EXTRA extraVerifyInfo;
memset(&extraVerifyInfo, 0x00, sizeof(TP_VERIFY_EXTRA)); // @D3A
/////////////////////////////////////////////////////////////////////////
// The field initialPolicyMappingInhibit in TP_INITIALPOLICY is not used
// by PKITP, therefore we do not set it.
/////////////////////////////////////////////////////////////////////////
initialPolicyPreferences.NumberofPolicyIdentifiers = NUM_POLICIES;
#if NUM_POLICIES != 0 //@D1A
initialPolicyPreferences.PolicyIdentifiers = policydata;
#else //@D1A
initialPolicyPreferences.PolicyIdentifiers = NULL; //@D1A
#endif //@D1A
initialPolicyPreferences.initialExplicitPolicy = INITIALExplicitPolicy;
initialPolicyPreferences.initialPolicyMappingInhibit = CSSM_FALSE;
initialPolicyPreferences.useCRLs = USECRLS;
/////////////////////////////////////////////////////////////////////////
// Initialize TP_EVIDENCE fields for printEvidence in case call
// to PKITP, is not successful.
pkixEvidence.CompleteCertGroup = NULL; /* @D0A */
pkixEvidence.CRL = NULL; /* @D0A */
pkixEvidence.Cert = NULL; /* @D0A */
/////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// The following fields in TP_VERIFY_EXTRA are not used by PKITP.
// CLHandle, PolicyIdentifiers and NumberofPolicyIdentifiers
// (not to be confused with fields of same name in TP_INITIALPOLICY structure),
// AnchorCerts and NumberofAnchorCerts.
// Therefore we do not set these fields below.
////////////////////////////////////////////////////////////////////////
extraVerifyInfo.DBList = datasources_ptr;
extraVerifyInfo.VerificationAbortOn = CSSM_TP_STOP_ON_POLICY;
extraVerifyInfo.CertToBeVerified = &certGroup
extraVerifyInfo.InitialPolicy = &initialPolicyPreferences
extraVerifyInfo.Evidence = &pkixEvidence
extraVerifyInfo.ValidationTime = time(0);
(void*)CSSM_TP_PassThrough(tphandle,
0,
0,
0,
0,
TP_VERIFY_PASSTHROUGH,
(void *)&extraVerifyInfo);
reportCertGroupVerify(extraVerifyInfo);
(void*)CSSM_TP_PassThrough(tphandle,
0,
0,
0,
0,
TP_FREE_EVIDENCE,
(void *)&extraVerifyInfo);
}
//==============================================================================
// function: reportCertGroupVerify
//==============================================================================
void
reportCertGroupVerify
(TP_VERIFY_EXTRA extraVerifyInfo)
{
//--------------------------------------
// report success or failure
//--------------------------------------
unsigned int reported_err = CSSM_GetError()->error;
printf("TP_VERIFY_PASSTHROUGH : ");
if (CSSM_FALSE == extraVerifyInfo.result)
{
printf("FAILED. Error code: %d\n",reported_err);
}
else
{
printf("PASSED\n");
}
//--------------------------------------
// report evidence
//--------------------------------------
printEvidence(extraVerifyInfo.Evidence);
}
void printEvidence(TP_EVIDENCE_PTR evidence_ptr)
{
if (evidence_ptr == NULL) return;
if (evidence_ptr->CompleteCertGroup)
{
printf("CompleteCertGroup was returned containing %d certificates at address %x\n",
evidence_ptr->CompleteCertGroup->NumCerts,
evidence_ptr->CompleteCertGroup->CertList);
}
else printf("CompleteCertGroup was NULL.\n");
if (evidence_ptr->CRL)
{
printf("CRL was returned of %d bytes (decimal) at address %x\n",
evidence_ptr->CRL->Length,
evidence_ptr->CRL->Data);
}
else printf("CRL was NULL.\n");
if (evidence_ptr->Cert)
{
printf("Cert (failed certificate) was returned of %d bytes (decimal) at address %x\n",
evidence_ptr->Cert->Length,
evidence_ptr->Cert->Data);
}
else printf("Cert was NULL.\n");
}
/*********************************************************************
* name: freeCertGroup - Free certificate data storage *
*********************************************************************/
void freeCertGroup(CSSM_CERTGROUP * certGroupPtr)
{
CSSM_DATA * certArray = certGroupPtr->CertList;
uint32 i;
uint32 certCount = certGroupPtr->NumCerts;
for (i=0; i <= certCount-1; i++)
{
free(certArray[i].Data);
}
free(certArray);
return;
}