z/OS Cryptographic Services PKI Services Guide and Reference
Previous topic | Next topic | Contents | Contact z/OS | Library | PDF


Code sample of the PKITP program (pkitpsamp.c)

z/OS Cryptographic Services PKI Services Guide and Reference
SA23-2286-00

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, &amp;datasources, &amp;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(&amp;certGroup, cert_files, num_certs);
      if (rc == 0)
        {
        verifyCertGroup(certGroup, &amp;datasources, tphandle);
        freeCertGroup(&amp;certGroup);
        }
      }
    } while (num_certs > 0);
  }
 disconnectTP(&amp;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(&amp;cssm_version, &amp;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*)&amp;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*)&amp;LDAPDL_GUID,
                                   &amp;moduleInfoPtr->Version,
                                   &amp;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*)&amp;bindParms
         userAuthentication.Credential = &amp;userCredential
         userAuthenticationPtr = &amp;userAuthentication
         }

      //------------------------------------------------------------
      // Open LDAP DL Database
      //------------------------------------------------------------
      datasources_ptr->DLDBHandle[z].DBHandle = CSSM_DL_DbOpen(LDAP_dlhandle,
                                        ldapserver[z].ldapserver,             //@D1C
                                        &amp;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(&amp;IBMOCEPDL_GUID,
                                   &amp;DL_version,
                                   &amp;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,
                               &amp;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*)&amp;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*)&amp;PKITP_GUID,
                                 &amp;moduleInfoPtr->Version,
                                 &amp;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(&amp;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          = &amp;certGroup
   extraVerifyInfo.InitialPolicy             = &amp;initialPolicyPreferences
   extraVerifyInfo.Evidence                  = &amp;pkixEvidence
   extraVerifyInfo.ValidationTime            = time(0);


   (void*)CSSM_TP_PassThrough(tphandle,
                              0,
                              0,
                              0,
                              0,
                              TP_VERIFY_PASSTHROUGH,
                              (void *)&amp;extraVerifyInfo);

   reportCertGroupVerify(extraVerifyInfo);
   (void*)CSSM_TP_PassThrough(tphandle,
                              0,
                              0,
                              0,
                              0,
                              TP_FREE_EVIDENCE,
                              (void *)&amp;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;
   }

Go to the previous page Go to the next page




Copyright IBM Corporation 1990, 2014