Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

Verify and Unwrap S/MIME, and get Information about CMS Signature

See more MIME Examples

Demonstrates calling the Verify method to verify and unwrap S/MIME. The MIME is restored to the original structure that it would have originally had prior to signing. The Verify method works with both detached signatures, as well as opaque/attached signatures.

Calls LastJsonData to get information about the signature(s) that were verified.

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Mime,
  Chilkat.DtObj,
  Chilkat.JsonObject;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  mime: TMime;
  verified: Boolean;
  json: TJsonObject;
  signingTime: TDtObj;
  authAttrSigningTimeUtctime: TDtObj;
  issuerCN: string;
  serial: string;
  strVal: string;
  certSerialNumber: string;
  certIssuerCN: string;
  certDigestAlgOid: string;
  certDigestAlgName: string;
  contentType: string;
  messageDigest: string;
  signingAlgOid: string;
  signingAlgName: string;
  authAttrContentTypeName: string;
  authAttrContentTypeOid: string;
  authAttrSigningTimeName: string;
  authAttrMessageDigestName: string;
  authAttrMessageDigestDigest: string;
  authAttr1_2_840_113549_1_9_15Der: string;
  authAttr1_3_6_1_4_1_311_16_4Der: string;
  i: Integer;
  count_i: Integer;

begin
  success := False;

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

  mime := TMime.Create;

  //  Load the signed MIME from a file...
  success := mime.LoadMimeFile('qa_data/mime/detached_sig.eml');
  if (success = False) then
    begin
      WriteLn(mime.LastErrorText);
      Exit;
    end;

  //  Verify the S/MIME and restore the MIME
  //  to the structure/content it had prior to signing.
  verified := mime.Verify();
  if (verified = False) then
    begin
      WriteLn(mime.LastErrorText);
      Exit;
    end;

  //  Examine the details of what was verified.
  json := TJsonObject.Create;
  mime.GetLastJsonData(json);

  json.EmitCompact := False;
  WriteLn(json.Emit());

  //  The code to parse the following JSON (i.e. extract desired information) is shown below..

  //  {
  //    "pkcs7": {
  //      "verify": {
  //        "certs": [
  //          {
  //            "issuerCN": "VeriSign Class 1 Public Primary Certification Authority - G3",
  //            "serial": "0702A21A85B84B659E180A6EE6F5A365"
  //          },
  //          {
  //            "issuerCN": "VeriSign Class 1 Public Primary Certification Authority - G3",
  //            "serial": "008B5B75568454850B00CFAF3848CEB1A4"
  //          },
  //          {
  //            "issuerCN": "Symantec Class 1 Individual Subscriber CA - G5",
  //            "serial": "619C55C32FF6BD1A7B7E0330D21C8F3C"
  //          }
  //        ],
  //        "digestAlgorithms": [
  //          "sha1"
  //        ],
  //        "signerInfo": [
  //          {
  //            "cert": {
  //              "serialNumber": "619C55C32FF6BD1A7B7E0330D21C8F3C",
  //              "issuerCN": "Symantec Class 1 Individual Subscriber CA - G5",
  //              "digestAlgOid": "1.3.14.3.2.26",
  //              "digestAlgName": "SHA1"
  //            },
  //            "contentType": "1.2.840.113549.1.7.1",
  //            "signingTime": "160428055000Z",
  //            "messageDigest": "2hJJVmO/jtaJV5uCKMFzIkRRvtY=",
  //            "signingAlgOid": "1.2.840.113549.1.1.1",
  //            "signingAlgName": "RSA-PKCSV-1_5",
  //            "authAttr": {
  //              "1.2.840.113549.1.9.3": {
  //                "name": "contentType",
  //                "oid": "1.2.840.113549.1.7.1"
  //              },
  //              "1.2.840.113549.1.9.5": {
  //                "name": "signingTime",
  //                "utctime": "160428055000Z"
  //              },
  //              "1.2.840.113549.1.9.4": {
  //                "name": "messageDigest",
  //                "digest": "2hJJVmO/jtaJV5uCKMFzIkRRvtY="
  //              },
  //              "1.2.840.113549.1.9.15": {
  //                "der": "MFAwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKA=="
  //              },
  //              "1.3.6.1.4.1.311.16.4": {
  //                "der": "MIG7MIG...7fgMw0hyPPA=="
  //              }
  //            }
  //          }
  //        ]
  //      }
  //    }
  //  }

  //  Use this online tool to generate parsing code from sample JSON: 
  //  Generate Parsing Code from JSON

  signingTime := TDtObj.Create;
  authAttrSigningTimeUtctime := TDtObj.Create;

  i := 0;
  count_i := json.SizeOfArray('pkcs7.verify.certs');
  while i < count_i do
    begin
      json.I := i;
      issuerCN := json.StringOf('pkcs7.verify.certs[i].issuerCN');
      serial := json.StringOf('pkcs7.verify.certs[i].serial');
      i := i + 1;
    end;

  i := 0;
  count_i := json.SizeOfArray('pkcs7.verify.digestAlgorithms');
  while i < count_i do
    begin
      json.I := i;
      strVal := json.StringOf('pkcs7.verify.digestAlgorithms[i]');
      i := i + 1;
    end;

  i := 0;
  count_i := json.SizeOfArray('pkcs7.verify.signerInfo');
  while i < count_i do
    begin
      json.I := i;
      certSerialNumber := json.StringOf('pkcs7.verify.signerInfo[i].cert.serialNumber');
      certIssuerCN := json.StringOf('pkcs7.verify.signerInfo[i].cert.issuerCN');
      certDigestAlgOid := json.StringOf('pkcs7.verify.signerInfo[i].cert.digestAlgOid');
      certDigestAlgName := json.StringOf('pkcs7.verify.signerInfo[i].cert.digestAlgName');
      contentType := json.StringOf('pkcs7.verify.signerInfo[i].contentType');
      json.DtOf('pkcs7.verify.signerInfo[i].signingTime',False,signingTime);
      messageDigest := json.StringOf('pkcs7.verify.signerInfo[i].messageDigest');
      signingAlgOid := json.StringOf('pkcs7.verify.signerInfo[i].signingAlgOid');
      signingAlgName := json.StringOf('pkcs7.verify.signerInfo[i].signingAlgName');
      authAttrContentTypeName := json.StringOf('pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.3".name');
      authAttrContentTypeOid := json.StringOf('pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.3".oid');
      authAttrSigningTimeName := json.StringOf('pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.5".name');
      json.DtOf('pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.5".utctime',False,authAttrSigningTimeUtctime);
      authAttrMessageDigestName := json.StringOf('pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.4".name');
      authAttrMessageDigestDigest := json.StringOf('pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.4".digest');
      authAttr1_2_840_113549_1_9_15Der := json.StringOf('pkcs7.verify.signerInfo[i].authAttr."1.2.840.113549.1.9.15".der');
      authAttr1_3_6_1_4_1_311_16_4Der := json.StringOf('pkcs7.verify.signerInfo[i].authAttr."1.3.6.1.4.1.311.16.4".der');
      i := i + 1;
    end;



  mime.Free;
  json.Free;
  signingTime.Free;
  authAttrSigningTimeUtctime.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.