Verifying signed messages


The following code samples demonstrate verification of a signed CMS message using PKIFv2.

Supported Languages

C++

void VerifyingSignedMessages()
{
      //Make sure the SignedData creation function has be executed (i.e.
      //make sure the global SignedData buffer is populated)
      if(g_signedDataBuffer == (CPKIFBuffer*)NULL)
      {
            cout << "No buffer to verify" << endl;
            return;
      } 

      //Decode the message into a ContentInfo object
      CPKIFContentInfo contentInfo;
      contentInfo.Decode((unsigned char*)g_signedDataBuffer->GetBuffer(),
            g_signedDataBuffer->GetLength());
 

      //Retrieve the content info and type from the ContentInfo object
      CPKIFBufferPtr content = contentInfo.GetContent();
      CPKIFOIDPtr contentType = contentInfo.GetContentType(); 

      //Make sure the content is a SignedData
      if(*contentType != *g_signedData)
      {
            cout << "Message does not contain a SignedData message." << endl;
            return;
      } 

      //Create a mediator object
      IPKIFMediatorPtr mediator = MakeDefaultMediator(); 

      //Create a SignedData object and pass the mediator to it
      CPKIFSignedData signedData;
      signedData.AddMediator(mediator); 

      //Create a CPKIFLDAPRepository colleague and setup directory info
      //(smime2.nist.gov hosts the PKITS test suite).  The port will be
      //set to 389 by default.  Use Set_Port to specify a non-standard port.
      CPKIFLDAPRepositoryPtr ldap(new CPKIFLDAPRepository());
      ldap->SetHost("smime2.nist.gov");       

      //When working with a mediator created via MakeDefaultMediator, cache-
      //related colleagues can be added optaining a pointer to the cache mediator
      //and adding the LDAP object to it directly.  An example is shown below.     

      CPKIFCacheMediator2* cacheMediator = mediator->GetMediator<CPKIFCacheMediator2>();
      cacheMediator->AddColleague(dynamic_pointer_cast<IPKIFColleague, CPKIFLDAPRepository>(ldap)); 

      //Decode the data from the ContentInfo object into the CPKIFSignedData
      signedData.Decode(content);     

      CMSVerificationStatus vStatus = NOT_VERIFIED; 

      //Verify the signature of the first signer info in the message.  The
      //Verify function returns true if the minimum status level passed via
      //the third parameter is satisfied.  Pass a less stringent minimum path
      //validation status, if desired (for example, if offline and CRLs are not
      //available).
      bool minStatusMet = signedData.Verify(0, vStatus/*,PVS_NOT_VALIDATED*/);
      if(!minStatusMet)
      {
            cout << "Minimum verification result not achieved."  << endl;
            switch(vStatus)
            {
            case CMS_SIGNATURE_INVALID:
                  //CMS signature is not valid.  Path and results are not available.
                  cout << "CMS status: the signature is not valid" << endl;
                  break;
            case NOT_VERIFIED:
                  //Verification failed prior to signature verification.
                  //Path and path results are not available.
                  cout << "CMS status: signature not verified" << endl;
                  break;
            case CMS_SIGNATURE_VERIFIED:
                  //Signature verified but path not built.
                  //Path and path results are not available.
                  cout << "CMS status: signature verified" << endl;
                  break;
            case REV_STATUS_INVALID:
            case CERT_PATH_INVALID:
            case CERT_PATH_VERIFIED:
            case REV_STATUS_VERIFIED:
                  {
                  //Signature verified and further status info can be obtained from
                  //path object and path validation results object.  Harvest the
                  //validation results and display using CPKIFPathLogger.
                  CPKIFPathValidationResultsPtr pvr = signedData.GetValidationResults();
                  CPKIFCertificatePathPtr path = signedData.GetPath();
                  if(pvr != (CPKIFPathValidationResults*)NULL &&
                        path != (CPKIFCertificatePath*)NULL)
                  {
                        CPKIFPathLogger::LogValidationResults(*pvr, *path,
                              "Sample application results", &cout);
                  }
                  break;
                  }
            default:
                  cout << "CMS status: unrecognized status" << endl;
                  break;
            }
      }
      else
      {
            cout << "CMS status: minimum status requirements met."  << endl; 

            //Harvest validation results and display using CPKIFPathLogger.
            CPKIFPathValidationResultsPtr pvr = signedData.GetValidationResults();
            CPKIFCertificatePathPtr path = signedData.GetPath();
            if(pvr != (CPKIFPathValidationResults*)NULL &&
                  path != (CPKIFCertificatePath*)NULL)
            {
                  CPKIFPathLogger::LogValidationResults(*pvr, *path,
                        "Sample application results", &cout);
            }
      } 

      //Extract the data from the message
      CPKIFEncapsulatedContentInfoPtr ecip = signedData.GetEncapsulatedContent();
      CPKIFBufferPtr data = ecip->GetContent(); 

      //Display the data
      cout << data->GetBuffer() << endl;
}

C#

public void VerifyingSignedMessages()
{
    //Make sure the SignedData creation function has be executed (i.e.
    //make sure the global SignedData buffer is populated)
    if (g_signedDataBuffer.get() == null)
    {
        Console.WriteLine("No buffer to verify");
        return;
    } 

    //Decode the message into a ContentInfo object
    CPKIFContentInfo contentInfo = new CPKIFContentInfo();
    contentInfo.Decode(g_signedDataBuffer.GetBuffer(), Convert.ToInt32(g_signedDataBuffer.GetLength())); 

    //Retrieve the content info and type from the ContentInfo object
    CPKIFBufferPtr content = contentInfo.GetContent();
    CPKIFOIDPtr contentType = contentInfo.GetContentType();

    //Make sure the content is a SignedData
    if (contentType.ToString() != pkif_module.g_signedData.ToString())
    {
        Console.WriteLine("Message does not contain a SignedData message.");
        return;
    } 

    //Create a mediator object
    IPKIFColleaguePtr mediator = pkif_module.MakeDefaultMediator(); 

    //Create a SignedData object and pass the mediator to it
    CPKIFSignedData signedData = new CPKIFSignedData();
    signedData.AddMediator(mediator); 

    //Create a CPKIFLDAPRepository colleague and setup directory info
    //(smime2.nist.gov hosts the PKITS test suite).  The port will be
    //set to 389 by default.  Use Set_Port to specify a non-standard port.
    IPKIFColleaguePtr ldapCol = pkif_module.make_NewCPKIFLDAPRepository();
    CPKIFLDAPRepositoryPtr ldap = pkif_module.cast_ToCPKIFLDAPRepository(ldapCol);
    ldap.SetHost("smime2.nist.gov"); 

    //When working with a mediator created via MakeDefaultMediator, cache-
    //related colleagues can be added optaining a pointer to the cache mediator
    //and adding the LDAP object to it directly.  An example is shown below.

    CPKIFCacheMediator2 cacheMediator = pkif_module.Get_CacheMediator(mediator);
    cacheMediator.AddColleague(ldapCol); 

    //Decode the data from the ContentInfo object into the CPKIFSignedData
    signedData.Decode(content);

     SWIGTYPE_p_CMSVerificationStatus vStatusSwig = pkif_module.Make_CMSVerificationStatus();

 

    //Verify the signature of the first signer info in the message.  The
    //Verify function returns true if the minimum status level passed via
    //the third parameter is satisfied.  Pass a less stringent minimum path
    //validation status, if desired (for example, if offline and CRLs are not
    //available).

    bool minStatusMet = signedData.Verify(0, vStatusSwig/*,PVS_NOT_VALIDATED*/);
    CMSVerificationStatus vStatus = pkif_module.Get_CMSVerificationStatusValue(vStatusSwig);
    if (!minStatusMet)
    {
        Console.WriteLine("Minimum verification result not achieved.");
        switch (vStatus)
        {
            case CMSVerificationStatus.CMS_SIGNATURE_INVALID:
                //CMS signature is not valid.  Path and results are not available.
                Console.WriteLine("CMS status: the signature is not valid");
                break;
            case CMSVerificationStatus.NOT_VERIFIED:
                //Verification failed prior to signature verification.
                //Path and path results are not available.
                Console.WriteLine("CMS status: signature not verified");
                break;
            case CMSVerificationStatus.CMS_SIGNATURE_VERIFIED:
                //Signature verified but path not built.
                //Path and path results are not available.
                Console.WriteLine("CMS status: signature verified");
                break;
            case CMSVerificationStatus.REV_STATUS_INVALID:
            case CMSVerificationStatus.CERT_PATH_INVALID:
            case CMSVerificationStatus.CERT_PATH_VERIFIED:
            case CMSVerificationStatus.REV_STATUS_VERIFIED:
                {
                    //Signature verified and further status info can be obtained from
                    //path object and path validation results object.  Harvest the
                    //validation results and display using CPKIFPathLogger.
                    CPKIFPathValidationResultsPtr pvr = signedData.GetValidationResults();
                    CPKIFCertificatePathPtr path = signedData.GetPath();
                    if (pvr.get() != null && path.get() != null)
                    {
                        string log = pkif_module.GetValidationResultsLog(pvr, path, "Sample application results");
                        Console.Write(log);
                    }
                    break;
                }
            default:
                Console.WriteLine("CMS status: unrecognized status");
                break;
        }
    }
    else
    {
        Console.WriteLine("CMS status: minimum status requirements met."); 

        //Harvest validation results and display using CPKIFPathLogger.
        CPKIFPathValidationResultsPtr pvr = signedData.GetValidationResults();
        CPKIFCertificatePathPtr path = signedData.GetPath();
        if (pvr.get() != null && path.get() != null)
        {          

            string log = pkif_module.GetValidationResultsLog(pvr, path, "Sample application results");
            Console.Write(log);
        }
    } 

    //Extract the data from the message
    CPKIFEncapsulatedContentInfoPtr ecip = signedData.GetEncapsulatedContent();
    CPKIFBufferPtr data = ecip.GetContent();   

    //Display the data
    Console.WriteLine(pkif_module.GetBufferAsString(data));
}

JAVA

public void VerifyingSignedMessages()
{
   
//Make sure the SignedData creation function has be executed (i.e.
    //make sure the global SignedData buffer is populated)
    if (g_signedDataBuffer.get() == null)
    {
        System.
out.println("No buffer to verify");
       
return;
    }

    //Decode the message into a ContentInfo object
    CPKIFContentInfo contentInfo = new CPKIFContentInfo();
    Long l =
g_signedDataBuffer.GetLength();
    contentInfo.Decode(
g_signedDataBuffer.GetBuffer(), l.intValue()); 

    //Retrieve the content info and type from the ContentInfo object
    CPKIFBufferPtr content = contentInfo.GetContent();
    CPKIFOIDPtr contentType = contentInfo.GetContentType(); 

 
    //Make sure the content is a SignedData
    if (contentType.ToString().compareTo(pkif_module.getG_signedData().ToString()) != 0)
    {
        System.
out.println("Message does not contain a SignedData message.");
       
return;
    }

    //Create a mediator object
    IPKIFColleaguePtr mediator = pkif_module.MakeDefaultMediator(); 

    //Create a SignedData object and pass the mediator to it
    CPKIFSignedData signedData = new CPKIFSignedData();
    signedData.AddMediator(mediator);
 

    //Create a CPKIFLDAPRepository colleague and setup directory info
    //(smime2.nist.gov hosts the PKITS test suite).  The port will be
    //set to 389 by default.  Use Set_Port to specify a non-standard port.
    IPKIFColleaguePtr ldapCol = pkif_module.make_NewCPKIFLDAPRepository();
    CPKIFLDAPRepositoryPtr ldap = pkif_module.cast_ToCPKIFLDAPRepository(ldapCol);
    ldap.SetHost(
"smime2.nist.gov"); 

    //When working with a mediator created via MakeDefaultMediator, cache-
    //related colleagues can be added optaining a pointer to the cache mediator
    //and adding the LDAP object to it directly.  An example is shown below. 

    CPKIFCacheMediator2 cacheMediator = pkif_module.Get_CacheMediator(mediator);
    cacheMediator.AddColleague(ldapCol);
 

    //Decode the data from the ContentInfo object into the CPKIFSignedData
    signedData.Decode(content); 

    SWIGTYPE_p_CMSVerificationStatus vStatusSwig = pkif_module.Make_CMSVerificationStatus(); 

    //Verify the signature of the first signer info in the message.  The
    //Verify function returns true if the minimum status level passed via
    //the third parameter is satisfied.  Pass a less Stringent minimum path
    //validation status, if desired (for example, if offline and CRLs are not
    //available).
    boolean minStatusMet = signedData.Verify(0, vStatusSwig/*,PVS_NOT_VALIDATED*/);
    CMSVerificationStatus vStatus = pkif_module.Get_CMSVerificationStatusValue(vStatusSwig);
   
if (!minStatusMet)
    {
        System.
out.println("Minimum verification result not achieved.");
       
if(vStatus == CMSVerificationStatus.CMS_SIGNATURE_INVALID)
        {
           
//CMS signature is not valid.  Path and results are not available.
            System.out.println("CMS status: the signature is not valid");
        }
       
else if(vStatus == CMSVerificationStatus.NOT_VERIFIED)
        {
           
//Verification failed prior to signature verification.
            //Path and path results are not available.
            System.out.println("CMS status: signature not verified");
        }
       
else if(vStatus == CMSVerificationStatus.CMS_SIGNATURE_VERIFIED)
        {
           
//Signature verified but path not built.
            //Path and path results are not available.
            System.out.println("CMS status: signature verified");
        }
       
else if(vStatus == CMSVerificationStatus.REV_STATUS_INVALID)
        {
        }
       
else if(vStatus == CMSVerificationStatus.CERT_PATH_INVALID)
        {
        }
       
else if(vStatus == CMSVerificationStatus.CERT_PATH_VERIFIED)
        {
        }
       
else if(vStatus == CMSVerificationStatus.REV_STATUS_VERIFIED)
        {
           
//Signature verified and further status info can be obtained from
            //path object and path validation results object.  Harvest the
            //validation results and display using CPKIFPathLogger.
            CPKIFPathValidationResultsPtr pvr = signedData.GetValidationResults();
            CPKIFCertificatePathPtr path = signedData.GetPath();
           
if (pvr.get() != null && path.get() != null)
            {
                String log = pkif_module.GetValidationResultsLog(pvr, path,
"Sample application results");
                System.
out.print(log);
            }
        }
       
else
        {
            System.
out.println("CMS status: unrecognized status");
        }
    }
   
else
    {
        System.
out.println("CMS status: minimum status requirements met."); 

        //Harvest validation results and display using CPKIFPathLogger.
        CPKIFPathValidationResultsPtr pvr = signedData.GetValidationResults();
        CPKIFCertificatePathPtr path = signedData.GetPath();
       
if (pvr.get() != null && path.get() != null)
        {           

            String log = pkif_module.GetValidationResultsLog(pvr, path, "Sample application results");
            System.
out.print(log);
        }
    }
 

    //Extract the data from the message
    CPKIFEncapsulatedContentInfoPtr ecip = signedData.GetEncapsulatedContent();
    CPKIFBufferPtr data = ecip.GetContent();
 

    //Display the data
    System.out.println(pkif_module.GetBufferAsString(data));
}