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

PKCS11 Certificate Chain

See more PKCS11 Examples

Demonstrates how to make CA certs available for the certificate chain to be included when creating a signature (using a PKCS11 compatible smart card / USB token) such as for PDF, XMLDSig, etc.

Note: This example requires Chilkat v9.5.0.88 or later.

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.XmlCertVault,
  Chilkat.Pkcs11,
  Chilkat.Cert;

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

procedure RunDemo;
var
  success: Boolean;
  pkcs11: TPkcs11;
  slotID: Integer;
  readWrite: Boolean;
  userType: Integer;
  pin: string;
  cert: TCert;
  certVault: TXmlCertVault;

begin
  success := False;

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

  //  Note: Chilkat's PKCS11 implementation runs on Windows, Linux, Mac OS X, and other supported operating systems.

  pkcs11 := TPkcs11.Create;

  //  You will use the DLL (or shared lib) provided by your smart card vendor, or a DLL compatible with your smart card.
  //  On Windows, if the DLL is located in C:\Windows\System32, specify only the filename.
  //  Otherwise provide the full path.
  pkcs11.SharedLibPath := 'bit4xpki.dll';

  success := pkcs11.Initialize();
  if (success = False) then
    begin
      WriteLn(pkcs11.LastErrorText);
      Exit;
    end;

  //  Pass -1 for the slotID to open a session on the first non-empty slot.
  slotID := -1;

  //  Open a session.
  readWrite := True;
  success := pkcs11.OpenSession(slotID,readWrite);
  if (success = False) then
    begin
      WriteLn(pkcs11.LastErrorText);
      Exit;
    end;

  //  Make it an authenticated session by calling Login.
  userType := 1;
  //  Make sure to use the correct PIN for your smart card..
  pin := '0000';
  success := pkcs11.Login(userType,pin);
  if (success = False) then
    begin
      WriteLn(pkcs11.LastErrorText);
      success := pkcs11.CloseSession();
      Exit;
    end;

  //  Get the certificate (on the smart card) that has a private key.
  cert := TCert.Create;
  success := pkcs11.FindCert('privateKey','',cert);
  if (success = True) then
    begin
      WriteLn('Cert with private key: ' + cert.SubjectCN);
    end
  else
    begin
      WriteLn('No certificates having a private key were found.');
      success := pkcs11.CloseSession();
      Exit;
    end;

  //  If the certificates in the chain of authentication were contained on the smart card,
  //  then Chilkat would already have them (via the FindCert function) and the certs in the chain will be automatically used
  //  as needed when signing occurs.

  //  If you have CA certs located elsewhere, such as in .cer files, you can make them available to Chilkat in the following way:

  certVault := TXmlCertVault.Create;
  //  Please review the methods available in the XML certificate vault class.  Different methods exist for adding certificates
  //  from various sources, such as PEM, PFX, or in-memory sources..
  success := certVault.AddCertFile('someDir/caIntermediateCert.cer');
  //  ...
  success := certVault.AddCertFile('someDir/caCert.cer');
  //  (Your code should check the return value to make sure it succeeded.)

  success := cert.UseCertVault(certVault);
  if (success = False) then
    begin
      WriteLn(cert.LastErrorText);
      success := pkcs11.CloseSession();
      Exit;
    end;

  //  --------------------------------------------------------------------------
  //  At this point, we have the cert (and certs in the chain of authentication) to be used for signing.
  //  The code for using the certificate in creating the digital signature, such as for a PDF, XML, etc., go here...

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

  //  Revert to an unauthenticated session by calling Logout.
  success := pkcs11.Logout();
  if (success = False) then
    begin
      WriteLn(pkcs11.LastErrorText);
      success := pkcs11.CloseSession();
      Exit;
    end;

  //  When finished, close the session.
  //  It is important to close the session (memory leaks will occur if the session is not properly closed).
  success := pkcs11.CloseSession();
  if (success = False) then
    begin
      WriteLn(pkcs11.LastErrorText);
      Exit;
    end;

  WriteLn('Success.');


  pkcs11.Free;
  cert.Free;
  certVault.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.