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

Set .pfx/.p12 Safe Bag Attributes

See more PFX/P12 Examples

Demonstrates how to set safebag attributes in a .pfx/.p12. This example creates a .pfx from a .pem containing a private key and certificates, but also sets PFX safebag attributes before writing the .pfx.

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.Pfx,
  Chilkat.StringBuilder,
  Chilkat.JsonObject;

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

procedure RunDemo;
var
  success: Boolean;
  pfx: TPfx;
  sbPem: TStringBuilder;
  password: string;
  forPrivateKey: Boolean;
  keyIdx: Integer;
  certIdx: Integer;
  pfx2: TPfx;
  json: TJsonObject;

begin
  success := False;

  //  We have a PEM containing one private key, and two certificates:
  //  The private key is an ECDSA private key.
  //  The private key is associated with the 1st certificate.
  //  The 2nd certificate is the issuer of the 1st certificate.

  //  -----BEGIN PRIVATE KEY-----
  //  ME0CAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEMzAxAgEBBCDgAn4Dal+0iEhIsYBk
  //  6SdSR344vyj0suhOIxsjmM19s6AKBggqhkjOPQMBBw==
  //  -----END PRIVATE KEY-----
  //  -----BEGIN CERTIFICATE-----
  //  MIIBXzCCAQSgAwIBAgIUGp2obfF61BG7QTsqpyT+VvxxJC0wCgYIKoZIzj0EAwIw
  //  DTELMAkGA1UEAwwCQ0EwHhcNMjAwMzI5MTU1MTEwWhcNMzAwMzI3MTU1MTEwWjAN
  //  MQswCQYDVQQDDAJFRTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEil+DhBUss8
  //  kMCjEWvZHA+jdy1mQ76a2HFd+5p+AcFGQxNeG8/HXZax7FFzcrczWrli25R8P8j1
  //  cqhwPY4HtwujQjBAMB0GA1UdDgQWBBTenwm6x4A4W5BzZ2OckKA2IFtPSTAfBgNV
  //  HSMEGDAWgBTx1U/gWiRhAASl6FV04DxP3XmcazAKBggqhkjOPQQDAgNJADBGAiEA
  //  rkqbz5t1M/CjqXSKE5ebBLQ3npF+q7GRC8C2ovDi/xoCIQDGve7OP/ppIDcCNonr
  //  +WSRf5M/6Wvw1lnEsAXf3nLTeQ==
  //  -----END CERTIFICATE-----
  //  -----BEGIN CERTIFICATE-----
  //  MIIBcDCCARWgAwIBAgIUAnQiKKy/PdLnH0A6vYKBq21w1JAwCgYIKoZIzj0EAwIw
  //  DTELMAkGA1UEAwwCQ0EwHhcNMjAwMzI5MTU1MTEwWhcNMzAwMzI3MTU1MTEwWjAN
  //  MQswCQYDVQQDDAJDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPB6yVvqt8cL
  //  EneRtnjoi87H0ATi+JP1w2qkz4GLOaPtFxAnV0LdQCuN91SGbAlKrSkhFyWWimjh
  //  Rqe9+b/1WCijUzBRMB0GA1UdDgQWBBTx1U/gWiRhAASl6FV04DxP3XmcazAfBgNV
  //  HSMEGDAWgBTx1U/gWiRhAASl6FV04DxP3XmcazAPBgNVHRMBAf8EBTADAQH/MAoG
  //  CCqGSM49BAMCA0kAMEYCIQCcIfssfrOruVYvqhxbLGeyc5ppEX53zUU35wIE2t7C
  //  fAIhAKhOTEvN+pdEn+cNwW3AEi7D08ZUQx3P80i4EnFPs0OQ
  //  -----END CERTIFICATE-----

  pfx := TPfx.Create;
  sbPem := TStringBuilder.Create;
  success := sbPem.LoadFile('qa_data/pfx/test_ecdsa.pem','utf-8');
  if (success = False) then
    begin
      WriteLn('Failed to load the PEM file.');
      Exit;
    end;

  //  The PEM in this example is unencrypted.  There is no password.
  password := '';
  success := pfx.LoadPem(sbPem.GetAsString(),password);
  if (success = False) then
    begin
      WriteLn(pfx.LastErrorText);
      Exit;
    end;

  //  Let's add some safebag attributes for the private key...
  forPrivateKey := True;
  keyIdx := 0;
  success := pfx.SetSafeBagAttr(forPrivateKey,keyIdx,'localKeyId','16777216','decimal');
  if (success = False) then
    begin
      WriteLn(pfx.LastErrorText);
      Exit;
    end;

  success := pfx.SetSafeBagAttr(forPrivateKey,keyIdx,'keyContainerName','{B99EB9E7-6AF7-42AF-A43A-D4B2225B7605}','ascii');
  if (success = False) then
    begin
      WriteLn(pfx.LastErrorText);
      Exit;
    end;

  success := pfx.SetSafeBagAttr(forPrivateKey,keyIdx,'storageProvider','Microsoft Software Key Storage Provider','ascii');
  if (success = False) then
    begin
      WriteLn(pfx.LastErrorText);
      Exit;
    end;

  //  Add the localKeyId safebag attribute to the 1st certificate.
  forPrivateKey := False;
  certIdx := 0;
  success := pfx.SetSafeBagAttr(forPrivateKey,certIdx,'localKeyId','16777216','decimal');
  if (success = False) then
    begin
      WriteLn(pfx.LastErrorText);
      Exit;
    end;

  //  Write the pfx.
  success := pfx.ToFile('secret','qa_output/ee.pfx');
  if (success = False) then
    begin
      WriteLn(pfx.LastErrorText);
      Exit;
    end;

  //  Let's load the .pfx we just wrote to see if the safebag attributes exist.
  pfx2 := TPfx.Create;
  success := pfx2.LoadPfxFile('qa_output/ee.pfx','secret');
  if (success = False) then
    begin
      WriteLn(pfx2.LastErrorText);
      Exit;
    end;

  //  Information about the contents of the PFX was collected in the call to LoadPfxFile.
  json := TJsonObject.Create;
  pfx2.GetLastJsonData(json);

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

  //  Shows what's in the PFX just loaded:

  //  {
  //    "authenticatedSafe": {
  //      "contentInfo": [
  //        {
  //          "type": "Data",
  //          "safeBag": [
  //            {
  //              "type": "pkcs8ShroudedKeyBag",
  //              "attrs": {
  //                "keyContainerName": "{B99EB9E7-6AF7-42AF-A43A-D4B2225B7605}",
  //                "msStorageProvider": "Microsoft Software Key Storage Provider",
  //                "localKeyId": "16777216"
  //              }
  //            }
  //          ]
  //        },
  //        {
  //          "type": "EncryptedData",
  //          "safeBag": [
  //            {
  //              "type": "certBag",
  //              "attrs": {
  //                "localKeyId": "16777216"
  //              },
  //              "subject": "EE",
  //              "serialNumber": "1a9da86df17ad411bb413b2aa724fe56fc71242d"
  //            },
  //            {
  //              "type": "certBag",
  //              "subject": "CA",
  //              "serialNumber": "02742228acbf3dd2e71f403abd8281ab6d70d490"
  //            }
  //          ]
  //        }
  //      ]
  //    }
  //  }


  pfx.Free;
  sbPem.Free;
  pfx2.Free;
  json.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.