Community articleUFLGetCertificateList function
Added by IBM contributorIBM on July 26, 2013
Rate this article 1 starsRate this article 2 starsRate this article 3 starsRate this article 4 starsRate this article 5 stars

This function locates all available certificates that can be used by a particular signature button. The certificates are filtered according to the signature engine defined in the signformat option of the button, and according to the filters defined in the signdetails option of the button.
This function returns the valid certificates in an undetermined order. This means that you cannot rely on the certificates being listed in the same order each time you call this function.
Note that each certificate in the list is tracked by reference counts. Once you are done with the certificates, you must release the reference counts to the certificates and free the array (see the example for details).

Function

   r_error UFLGetCertificateList(
      formNodeP buttonNode,
      r_charP theFilters,
      SecurityUserStatusType *theStatus,
      Certificate ***certList,
      r_long *certCount
   );


Parameters

Table 1. Function parameters
ExpressionTypeDescription
buttonNode formNodePThe node that represents the signature button.
theFiltersr_charPA string that is used to filter the subject attribute of the certificate. If the subject attribute include this substring, then that certificate will be listed.
For example, you might filter against a name, such as "John Doe", or an e-mail address, such as "jdoe@ibm.com".
Note that this filter is in addition to the other filters defined in the signdetails option of the button.
If NULL is passed, then only the filters in the signdetails option are used.
theStatusSecurityUserStatusType*This is a status flag that reports whether the operation was successful. Possible values are:
SUSTATUS_OK — the operation was successful.
SUSTATUS_CANCELLED — the operation was cancelled by the user.
SUSTATUS_INPUT_REQUIRED — the operation required user input, but could not receive it (for example, it was run on a server with no user).
certList Certificate***The list of certificates that the function locates. Note that each certificate object is tracked by reference counts, and must be released. Furthermore, the array must also be freed.
certCount r_long*The number of certificates that the function located.


Returns

OK on success or an error code on failure.

Example

In the following example, UFLDereferenceEx is used to locate a specific signature button node. UFLGetCertificateList is then used to get a list of valid certificates for that button. Next, Certificate_GetDataByPath is used to search for the IBM® Forms Server certificate, which UFLSignForm then uses to sign the button. Finally, the reference counts to the certificate list and the signature object are released.
   r_error signButton(formNodeP form)
   {
   SecurityUserStatusType theStatus;
   formNodeP buttonNode;
   Certificate **certList;
   Signature *theSignature;
   r_charP signerCommonName;
   r_boolean encodedResult;
   r_error error;
   r_long certCount;
   r_long correctCert = -1;
   r_long i;
 
      if ((buttonNode = UFLDereferenceEx(form, NULL, "PAGE1.SIGNBUTTON", 
         0, UFL_ITEM_REFERENCE, NULL)) == NULL)
      {
         fprintf(stderr, "Could not find SIGNBUTTON node.\n");
         return(NOTOK);
      }
         
      if ((error = UFLGetCertificateList(buttonNode, NULL, &theStatus, 
         &certList, &certCount)) != OK)
      {
         fprintf(stderr, "UFLGetCertificateList error %hd.\n", error);
         return(NOTOK);
      }
 
      /* Check the status, in case the process required user input. */
 
      if (theStatus != SUSTATUS_OK)
      {
         fprintf(stderr, "User input required to retrieve certificate list.
            /n");
         return(NOTOK);
      }
      /* Iterate through the certificates to find one with a common name of
         IBM Forms Server */
 
      for (i=0; i<certCount; i++)
      {
         if ((error = Certificate_GetDataByPath(certList[i], 
            "SigningCert: Subject: CN", NOTOK, &encodedResult, 
            &signerCommonName)) != OK)
         {
            fprintf(stderr, "Certificate_GetDataByPath error %hd./n",
               error);
            return(NOTOK);
         }
         if (cp_strcmp(signerCommonName, "IBM Forms Server") == OK)
         {
            correctCert = i;
            cp_free(signerCommonName);
            break;
         }
         cp_free(signerCommonName);
      }
 
      /* If the correct certificate was not located, report the problem and
         exit the function. */
 
      if (correctCert == -1)
      {
         fprintf(stderr, "Could not locate required certificate.");
         return(NOTOK);
      }
 
      /* Use the IBM Forms Server certificate to sign the form */
 
      if ((error = UFLSignForm(buttonNode, certList[correctCert], NULL,
         &theStatus, &theSignature)) != OK)
      {
         fprintf(stderr, "UFLSignForm error %hd.\n", error);
         return(NOTOK);
      }
      
      /* Check the status in case the process required user input. */
 
      if (theStatus != SUSTATUS_OK)
      {
         fprintf(stderr, "User input required to sign form./n");
         return(NOTOK);
      }
 
      /* Release each certificate object in the array */
 
      for(i=0; i<certCount; i++)
      {
         IFSObject_ReleaseRef((IFSObject*)certCount[i]);
      }
 
      /* Free the array */
 
      pe_free(certList);
 
      /* Relase the signature object */
 
      IFSObject_ReleaseRef((IFSObject*)theSignature);
 
      return(OK);
   }


Parent topic:
FormNodeP functions