Sample code for 30+ languages & platforms
Delphi DLL

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 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, Mime, DtObj, JsonObject;

...

procedure TForm1.Button1Click(Sender: TObject);
var
success: Boolean;
mime: HCkMime;
verified: Boolean;
json: HCkJsonObject;
signingTime: HCkDtObj;
authAttrSigningTimeUtctime: HCkDtObj;
issuerCN: PWideChar;
serial: PWideChar;
strVal: PWideChar;
certSerialNumber: PWideChar;
certIssuerCN: PWideChar;
certDigestAlgOid: PWideChar;
certDigestAlgName: PWideChar;
contentType: PWideChar;
messageDigest: PWideChar;
signingAlgOid: PWideChar;
signingAlgName: PWideChar;
authAttrContentTypeName: PWideChar;
authAttrContentTypeOid: PWideChar;
authAttrSigningTimeName: PWideChar;
authAttrMessageDigestName: PWideChar;
authAttrMessageDigestDigest: PWideChar;
authAttr1_2_840_113549_1_9_15Der: PWideChar;
authAttr1_3_6_1_4_1_311_16_4Der: PWideChar;
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 := CkMime_Create();

// Load the signed MIME from a file...
success := CkMime_LoadMimeFile(mime,'qa_data/mime/detached_sig.eml');
if (success = False) then
  begin
    Memo1.Lines.Add(CkMime__lastErrorText(mime));
    Exit;
  end;

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

// Examine the details of what was verified.
json := CkJsonObject_Create();
CkMime_GetLastJsonData(mime,json);

CkJsonObject_putEmitCompact(json,False);
Memo1.Lines.Add(CkJsonObject__emit(json));

// 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 := CkDtObj_Create();
authAttrSigningTimeUtctime := CkDtObj_Create();

i := 0;
count_i := CkJsonObject_SizeOfArray(json,'pkcs7.verify.certs');
while i < count_i do
  begin
    CkJsonObject_putI(json,i);
    issuerCN := CkJsonObject__stringOf(json,'pkcs7.verify.certs[i].issuerCN');
    serial := CkJsonObject__stringOf(json,'pkcs7.verify.certs[i].serial');
    i := i + 1;
  end;

i := 0;
count_i := CkJsonObject_SizeOfArray(json,'pkcs7.verify.digestAlgorithms');
while i < count_i do
  begin
    CkJsonObject_putI(json,i);
    strVal := CkJsonObject__stringOf(json,'pkcs7.verify.digestAlgorithms[i]');
    i := i + 1;
  end;

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

CkMime_Dispose(mime);
CkJsonObject_Dispose(json);
CkDtObj_Dispose(signingTime);
CkDtObj_Dispose(authAttrSigningTimeUtctime);

end;