Sample code for 30+ languages & platforms
Delphi DLL

Verify Opaque Signature and Retrieve Signing Certificates

See more Digital Signatures Examples

Demonstrates how to verify a PCKS7 opaque digital signature (signed data), extract the original file/data, and then extract the certificate(s) that were used to sign.

Chilkat Delphi DLL Downloads

Delphi DLL
uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, BinData, CertChain, Cert, Crypt2;

...

procedure TForm1.Button1Click(Sender: TObject);
var
success: Boolean;
crypt: HCkCrypt2;
binData: HCkBinData;
cert: HCkCert;
certChain: HCkCertChain;
numCerts: Integer;
i: Integer;

begin
success := False;

// This example assumes the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

crypt := CkCrypt2_Create();

// Verify a PKCS7 signed-data (opaque signature) file and extract the original content to a file.
success := CkCrypt2_VerifyP7M(crypt,'qa_data/p7m/opaqueSig.p7','qa_output/originalData.dat');
if (success = False) then
  begin
    Memo1.Lines.Add(CkCrypt2__lastErrorText(crypt));
    Exit;
  end;

// Alternatively, we can do it in memory...
binData := CkBinData_Create();
success := CkBinData_LoadFile(binData,'qa_data/p7m/opaqueSig.p7');
// Your app should check for success, but we'll skip the check for brevity..

// If verified, the signature is unwrapped and binData is replaced with the original data that was signed.
success := CkCrypt2_OpaqueVerifyBd(crypt,binData);
if (success = False) then
  begin
    Memo1.Lines.Add(CkCrypt2__lastErrorText(crypt));
    Exit;
  end;

// For our testing, we signed some text, so we can get it from the binData..
Memo1.Lines.Add('Original Data:');
Memo1.Lines.Add(CkBinData__getString(binData,'utf-8'));

// After any method call that verifies a signature, the crypt object will contain the certificate(s)
// that were used for signing (assuming the X.509 certs were available in the signature, which is typically the case).

// Get each signing certificate, and build the certificate chain for each.
cert := CkCert_Create();
certChain := CkCertChain_Create();
numCerts := CkCrypt2_getNumSignerCerts(crypt);
i := 0;
while i < numCerts do
  begin
    CkCrypt2_LastSignerCert(crypt,i,cert);
    Memo1.Lines.Add(CkCert__subjectDN(cert));

    success := CkCert_BuildCertChain(cert,certChain);
    if (success = False) then
      begin
        Memo1.Lines.Add(CkCert__lastErrorText(cert));
        Exit;
      end;

    i := i + 1;
  end;

CkCrypt2_Dispose(crypt);
CkBinData_Dispose(binData);
CkCert_Dispose(cert);
CkCertChain_Dispose(certChain);

end;