000018485 - How to skip invalid certificates when using the RSA BSAFE Cert-C CryptoAPI Service Provider

Document created by RSA Customer Support Employee on Jun 16, 2016Last modified by RSA Customer Support Employee on Apr 21, 2017
Version 2Show Document
  • View in full screen mode

Article Content

Article Number000018485
Applies ToRSA BSAFE Cert-C 1.0
RSA BSAFE Cert-C 2.0
IssueHow to skip invalid certificates when using the RSA BSAFE Cert-C CryptoAPI Service Provider
Currently when enumerating certificates using the CryptoAPI Service Provider, if there is a bad certificate (one for which C_SetCertBER returns a non-zero code) Cert-C will stop the enumeration and destroy the iterator, making it impossible to resume the enumeration.  However, you can add a fix in the provider code so that Cert-C will skip a bad certificate and load the next one.
CauseThe problem is that currently in Cert-C, whenever a service provider implementation of SelectFirst/NextCert returns a non-zero error code, the ITERATOR is destroyed, so there is no way for the API to just ignore a non-zero code from C_SelectFirst/NextCert to move to the next cert.
ResolutionModify the provider's behavior to keep "incrementing" the ITERATOR if we fail to set a cert object properly.  One possible way to do this is to modify the provider/db/capi/capiprov.c, lines 1087-1104 (in SelectCert()) as follows:

/* [NEW] Keep trying until we successfully get a cert.  you may want to
modify this so that we set an upper limit to the number of certs to skip, guarding against getting stuck in an infinite loop... */
for (;;) {
   MS_CAPI_HANDLES * pHandle2 = (MS_CAPI_HANDLES *) pHandle;

/* Enumerate all the certificate contexts in the store */
    PCCERT_CONTEXT pCertContext =
   CertEnumCertificatesInStore (
      pHandle2->hCertStore,        /* IN HCERTSTORE hCertStore */
     ((MS_CAPI_CERT_ITERATOR *) *ppIterator)->pPrevCertContext) ;       /* IN PCCERT_CONTEXT pPrevCertContext*/
   ((MS_CAPI_CERT_ITERATOR *) *ppIterator)->pPrevCertContext = pCertContext ;

   if (!pCertContext)
      /* Error getting certificate */
      nRetStat = E_NOT_FOUND ;
      break;  /* [NEW] break out when there are no more certs */
   else { /* [NEW] break out on success, otherwise, we'll update the
               iterator  and try again */
      /* Insert the cert context into the list object */
      nRetStat = InsertCertContextIntoListObj (pCtx, pCertContext,
                                                                  pCertListObj) ;
     if (nRetStat == 0)
   }   } /* end for loop */

To further aid in error checking, you can add code in
InsertCertContextIntoListObj which logs an error when C_SetCertBER fails and perhaps write that binary data out to a file for further debugging later.

You will need to rebuild the certcsp.lib library - the release notes have details on this (especially a warning not to do a 'make clean' because there are some precompiled objects which we don't supply source for that need to be pulled into the certcsp library).
Legacy Article IDa2275