Community articleCertificate_GetDataByPath function
Added by IBM contributorIBM on August 16, 2011
Rate this article 1 starsRate this article 2 starsRate this article 3 starsRate this article 4 starsRate this article 5 stars




Description

This function retrieves a piece of data from a certificate object.

Function

   r_error Certificate_GetDataByPath(
      Certificate *theCertificate,
      r_charP thePath,
      r_boolean tagData,
      r_boolean *encoded,
      r_charP *theData
		);
	  


Parameters

Table 1. Function parameters
ExpressionTypeDescription
theCertificate Certificate*The certificate object you want to query.
thePathr_charPThe path to the data you want to retrieve. See the Notes section below for more information on data paths.
tagDatar_booleanOK if the path should be prepended to the data, or NOTOK if not. If the path is prepended, an equals sign (=) is used as a separator.
For example, suppose the path is "Issuer: CN" and the data is "IBM®". If OK, the path will be prepended, producing "CN=IBM". If NOTOK, the path will not be prepended, and the result will be "IBM".
encodedr_boolean*OK if the return data is base 64 encoded, or NOTOK if not. The function returns binary data in base 64 encoding.
theData r_charP*The data that the function locates. This is NULL if no data is found. Note that this string must be freed.


Notes

About data paths:
Data paths describe the location of information within a certificate, just like file paths describe the location of files on a disk. You describe the path with a series of colon separated tags. Each tag represents either a piece of data, or an object that contains further pieces of data (just like directories can contain files and subdirectories).
For example, to retrieve the version of a certificate, you would use the following data path:
   Version

However, to retrieve the subject's common name, you first need to locate the subject and then the common name within the subject, as follows:
   Subject: CN

Some tags may contain more than one piece of information. For example, the issuer's organizational unit may contain a number of entries. You can either retrieve all of the entries as a comma separated list, or you can specify a specific entry by using a zero-based element number.
For example, the following path would retrieve a comma separated list:
   Issuer: OU

Adding an element number of 0 would retrieve the first organizational unit in the list, as shown:
   Issuer: OU: 0


Certificate tags:
The following table lists the tags available in a certificate object:
Table 2. certificate object tag names
TagDescription
SubjectThe subject's distinguished name. This is an object that contains further information, as detailed in Distinguished Name Tags .
IssuerThe issuer's distinguished name. This is an object that contains further information, as detailed in Distinguished Name Tags .
IssuerCertThe issuer's certificate. This is an object that contains the complete list of certificate tags.
EngineThe security engine that generated the certificate. This is an object that contains further information, as detailed in Security Engine Tags .
VersionThe certificate version.
BeginDateThe date on which the certificate became valid.
EndDateThe date on which the certificate expires.
SerialThe certificates serial number.
SignatureAlgThe signature algorithm used to sign the certificate.
PublicKeyThe certificate's public key.
FriendlyNameThe certificate's friendly name.


Distinguished name tags:
The following table lists the tags available in a distinguished name object:
Table 3. distinguished tag names
TagDescription
CNThe common name.
EThe email address.
TThe title.
OThe organization.
OUThe organizational unit.
CThe country.
LThe locality.
STThe state.
AllThe entire distinguished name.


Security engine tags:
The following table lists the tags available in the security engine object:
Table 4. security engine tag names
TagDescription
NameThe name of the security engine used by the server.
HelpThe help text for the security engine.
HashAlgA hash algorithm supported by the security engine.


Returns

OK on success or an error code on failure.

Example

The following function uses UFLDereferenceEx to locate a signature button in the form. It then uses UFLGetCertificateList to get a list of valid certificates for that button. Next, the function cycles through the returned certificates, uses Certificate_GetDataByPath to get the common name for each certificate, and identifies the certificate with a common name of "IBM Forms Server". Then the function uses UFLSignForm to sign the form with the server's certificate. Finally, the certificate and signature objects are released.
   r_error serverSign(formNodeP form)
   {
   SecurityUserStatusType theStatus;
   formNodeP buttonNode;
   Certificate **certList;
   Signature *theSignature;
   r_charP signerCommonName;
   r_boolean encodedResult;
   r_long certCount;
   r_long correctCert = -1;
   r_error error;
   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);
      }
 
      for (i=0; i<certCount; i++)
      {
         if ((error = Certificate_GetDataByPath(certList [i], 
            "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 (correctCert == -1)
      {
         fprintf(stderr, "Could not locate required certificate.\n");
         return(NOTOK);
      }
            
      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*)certList [i]);
      }
 
      /* Free the array */
 
      pe_free(certList);
 
      /* Release the signature object */
 
      IFSObject_ReleaseRef((IFSObject*)theSignature);
 
      return(OK);
   }


Parent topic:
Certificate functions