sgcSign 2026.5 — Authenticode, EU eIDAS Pack & 9 Employment Profiles

· Releases

Only one month after the initial launch, sgcSign 2026.5 ships a major expansion of the library. The release adds Microsoft Authenticode signing for Windows binaries, three new code-distribution signers (ClickOnce, NuGet, VSIX), a complete EU eIDAS compliance pack (ASiC containers, LOTL / EUTL trust list, Cloud Signature Consortium remote signing), nine pre-tuned country employment profiles, a Bulgarian Peppol BIS Billing 3.0 profile, a native QR Code generator, ECDSA P-256/384/521 plus RSA-PSS support, full CI/CD integrations, and an extensive set of XAdES / PFX conformance fixes.

This post walks through the highlights, with ready-to-paste Delphi snippets for every new component.

Microsoft Authenticode

TsgcAuthenticodeSigner signs Windows Portable Executable files (.exe, .dll, .sys) per the Authenticode specification. The signer parses the PE, hashes it with the Authenticode algorithm (skipping the checksum and the existing certificate table), builds a full PKCS#7 SignedData blob with the SPC indirect data content, and appends it to the binary's certificate table.

Hashes from SHA-1 through SHA-512 are supported, RFC 3161 timestamps are embedded as unsigned attributes, and AppendSignature := True produces nested signatures (e.g. SHA-1 + SHA-256 dual signing for legacy Windows compatibility).

uses
  sgcSign_Authenticode, sgcSign_KeyProvider_PFX, sgcSign_TSAClient;

var
  oSigner: TsgcAuthenticodeSigner;
  oPFX: TsgcPFXKeyProvider;
  oTSA: TsgcTSAClient;
begin
  oPFX := TsgcPFXKeyProvider.Create(nil);
  oPFX.FileName := 'codesign.pfx';
  oPFX.Password := 'secret';

  oTSA := TsgcTSAClient.Create(nil);
  oTSA.URL := 'http://timestamp.digicert.com';

  oSigner := TsgcAuthenticodeSigner.Create(nil);
  try
    oSigner.KeyProvider := oPFX;
    oSigner.TSAClient   := oTSA;
    oSigner.Hash        := ahSHA256;     // ahSHA1 / ahSHA256 / ahSHA384 / ahSHA512
    oSigner.Level       := alT;          // alBES or alT (with timestamp)
    oSigner.Description := 'My Application';
    oSigner.URL         := 'https://www.example.com';
    oSigner.SignFile('MyApp.exe', 'MyApp-signed.exe');
  finally
    oSigner.Free; oTSA.Free; oPFX.Free;
  end;
end;

Verification is symmetric. TsgcAuthenticodeVerifier.Verify returns a record with the result, the computed and embedded hashes, the signer subject/issuer, and whether a timestamp is present:

var
  oVer: TsgcAuthenticodeVerifier;
  oRes: TsgcAuthenticodeVerifyResult;
begin
  oVer := TsgcAuthenticodeVerifier.Create(nil);
  try
    oRes := oVer.Verify('MyApp-signed.exe');
    if oRes.Valid then
      ShowMessage('Signed by ' + oRes.SubjectName)
    else
      ShowMessage('Invalid: ' + oRes.ErrorMessage);
  finally
    oVer.Free;
  end;
end;

Hash-only Authenticode signing

Large CI artifacts (installers, runtimes, drivers) make uploading the full PE to a remote signer painful. The new hash-only signing flow lets the client compute the Authenticode hash locally and send only the 32-byte digest to the sgcSign Server. The server returns the unattached PKCS#7 blob, and the client embeds it back into the binary — cutting multi-megabyte uploads to a few KB on bandwidth-constrained agents.

// Local: compute the hash with sgcSign_PE_Hasher, POST it to the server,
// receive the SignedData blob, then append it to the PE's certificate table.
var
  oSigner: TsgcAuthenticodeSigner;
  vHash, vPKCS7: TBytes;
begin
  // vHash := ComputePEHash('MyApp.exe', haSHA256);
  vPKCS7 := oSigner.SignHash(vHash, ahSHA256);
  // EmbedPKCS7IntoPE('MyApp.exe', vPKCS7, 'MyApp-signed.exe');
end;

The same operation is exposed by the server's POST /api/v1/sign/authenticode/hash endpoint, the sgcsign sign --prehash CLI flag, and the TsgcSignClient.SignAuthenticodeHashAsync method on the .NET SDK.

ClickOnce, NuGet and VSIX signers

Three new signers cover the Microsoft developer-distribution ecosystem.

TsgcClickOnceSigner signs .application deployment manifests and .exe.manifest application manifests using enveloped W3C XML-DSig, matching the output of Microsoft mage.exe. The signer rewrites the publisherIdentity node with the certificate's issuerKeyHash.

uses sgcSign_ClickOnce;

var oCO: TsgcClickOnceSigner;
begin
  oCO := TsgcClickOnceSigner.Create(nil);
  try
    oCO.KeyProvider   := oPFX;
    oCO.Hash          := haSHA256;
    oCO.PublisherName := 'My Company';
    oCO.SignManifestFile('MyApp.application', 'MyApp-signed.application');
  finally
    oCO.Free;
  end;
end;

TsgcNuGetSigner signs .nupkg author packages, producing a CMS/PKCS#7 SignedData blob (signing certificate v2, commitment-type "proof of origin") with an optional RFC 3161 countersignature.

uses sgcSign_NuGet;

var oNu: TsgcNuGetSigner;
begin
  oNu := TsgcNuGetSigner.Create(nil);
  try
    oNu.KeyProvider := oPFX;
    oNu.TSAClient   := oTSA;
    oNu.Hash        := haSHA256;
    oNu.SignPackageFile('MyLib.1.0.0.nupkg', 'MyLib.1.0.0.signed.nupkg');
  finally
    oNu.Free;
  end;
end;

TsgcVSIXSigner implements OPC (Open Packaging Convention) digital signatures for Visual Studio extensions, computing per-part XML-DSig references and rewriting [Content_Types].xml and the package _rels/.rels.

uses sgcSign_VSIX;

var oVX: TsgcVSIXSigner;
begin
  oVX := TsgcVSIXSigner.Create(nil);
  try
    oVX.KeyProvider := oPFX;
    oVX.Hash        := haSHA256;
    oVX.SignPackageFile('MyExt.vsix', 'MyExt-signed.vsix');
  finally
    oVX.Free;
  end;
end;

All three reuse the same IsgcKeyProvider interface as the existing XAdES / PAdES / CAdES signers, so an AWS KMS, Azure Trusted Signing or PKCS#11 token configured for invoice signing can be reused for binary signing with no extra plumbing.

EU eIDAS / compliance pack

This release introduces the eIDAS pack — three new units that, together, let a Delphi application validate a signature against the official EU trust framework and produce long-term archival containers.

ASiC containers (ETSI EN 319 162-1)

sgcSign_ASiC builds and parses ASiC-S (single document) and ASiC-E (multiple documents) containers in both XAdES and CAdES flavours. Output is a deterministic ZIP with the mimetype entry first and the signature placed under META-INF/.

uses sgcSign_ASiC;

var
  oDocs: TsgcASiCDocumentArray;
  vBytes: TBytes;
begin
  SetLength(oDocs, 1);
  oDocs[0].Name := 'invoice.xml';
  oDocs[0].Data := TFile.ReadAllBytes('invoice.xml');

  // aSignatureXML comes from TsgcXAdESSigner (detached signature over the doc)
  vBytes := TsgcASiCContainer.BuildXAdES(apASiCE, oDocs, vXAdESSignature);
  TFile.WriteAllBytes('invoice.asice', vBytes);
end;

LOTL / EUTL trust list

sgcSign_TrustList downloads the EU List of Trusted Lists, follows the per-Member-State trust list pointers, and parses each TSPService entry. The result is an in-memory catalogue of ~3,600 services across 31 Member States. The IsQualifiedAtTime lookup classifies any certificate as "issued by a Qualified TSP" at a given signing time — the operation needed to upgrade a signature from advanced (AdES) to qualified (QES) under eIDAS Article 25.

Cloud Signature Consortium (CSC v2)

TsgcCSCKeyProvider is an IsgcKeyProvider implementation for the Cloud Signature Consortium API v2 — the European standard for remote qualified signing used by Buypass, Certinomis, Globalsign EU, InfoCert, Namirial, Trust Pro and other QTSPs. The provider handles Basic / OAuth2 / OTP auth, lists the user's credentials, fetches the certificate chain, and performs hash-only remote signing using SAD authorization.

uses sgcSign_KeyProvider_CSC, sgcSign_XAdES;

var oCSC: TsgcCSCKeyProvider; oX: TsgcXAdESSigner;
begin
  oCSC := TsgcCSCKeyProvider.Create(nil);
  oCSC.BaseURL    := 'https://csc.example-qtsp.eu/csc/v2';
  oCSC.AuthMethod := cscOAuth2;
  oCSC.OAuthClientID     := 'my-client-id';
  oCSC.OAuthClientSecret := 'my-client-secret';
  oCSC.CredentialID      := oCSC.ListCredentials[0];
  oCSC.PIN := '1234';
  oCSC.OTP := '987654';      // pushed via SMS / app
  oCSC.LoadCredentialInfo;

  oX := TsgcXAdESSigner.Create(nil);
  oX.KeyProvider := oCSC;
  oX.Profile     := spEIDAS;
  oX.SignXML(vXML);
end;

Nine employment profiles

Nine pre-tuned profiles target European labour-law documents (employment contracts, payslips, transfer agreements):

ProfileCountryLevelC14NTSAOCSP
spEmploymentDEGermanyB-LTExclusiveYesYes
spEmploymentITItalyB-LTC14N 1.0YesYes
spEmploymentESSpainB-TExclusiveYesNo
spEmploymentFRFranceB-TExclusiveYesNo
spEmploymentPLPolandB-TExclusiveYesNo
spEmploymentATAustriaB-LTExclusiveYesYes
spEmploymentBEBelgiumB-LTExclusiveYesYes
spEmploymentPTPortugalB-LTExclusiveYesYes
spEmploymentNLNetherlandsB-TExclusiveYesNo

A new EU_Employment demo ships the full pipeline (sign → ASiC-E package → LOTL verification → QTSP classification).

Bulgarian Peppol BIS Billing 3.0

The new TsgcProfilePeppolBG profile signs Bulgarian UBL 2.1 invoices (BGN currency, 20% VAT, BG VAT / EIK, BG IBAN, scheme ID 9926 endpoint) at XAdES B-T with exclusive C14N. The Delphi and C++Builder demos ship a fully populated invoice template.

uses sgcSign_XAdES, sgcSign_Types;

var oSigner: TsgcXAdESSigner;
begin
  oSigner := TsgcXAdESSigner.Create(nil);
  try
    oSigner.KeyProvider := oPFX;
    oSigner.TSAClient   := oTSA;
    oSigner.Profile     := spPeppolBG;
    oSigner.SignXMLFile('invoice_bg.xml', 'invoice_bg_signed.xml');
  finally
    oSigner.Free;
  end;
end;

CI/CD integrations

sgcSign Server now ships first-class artifacts for every common pipeline:

QR Code generator

For TicketBAI, VeriFactu and similar profiles that require a QR code on the printable invoice, the new sgcSign_QRCode unit ships a pure-Pascal generator implementing ISO/IEC 18004 in byte mode — all four ECC levels, versions 1 through 40, GF(256) Reed-Solomon, full mask-penalty scoring — with a TBitmap renderer. No external DLL, no licensing surprises.

uses sgcSign_QRCode, Graphics;

var
  oMatrix: TQRMatrix;
  oBmp: TBitmap;
begin
  oMatrix := GenerateQRCode(
    'https://tbai.eus/QURL/123456789-A?cr=42',
    qrECM);

  oBmp := TBitmap.Create;
  try
    RenderQRMatrix(oMatrix, oBmp, 5, 4);    // 5 px / module, 4-module border
    oBmp.SaveToFile('invoice_qr.bmp');
  finally
    oBmp.Free;
  end;
end;

ECDSA P-256 / P-384 / P-521 and RSA-PSS

TsgcPEMKeyProvider now imports EC private keys via Windows BCrypt CNG (ECCPRIVATEBLOB) and signs with raw r||s output for XML-DSig. A new SignDataPSS method produces RSA-PSS signatures (SHA-256, salt = 32 bytes) using BCRYPT_PAD_PSS — required by an increasing number of national e-invoicing profiles.

On the verification side, TsgcSignatureVerifier imports EC public keys from BCRYPT_ECCPUBLIC_BLOB and validates ECDSA signatures for the same three curves in both the XAdES SignatureValue and the raw VerifyData code paths.

To make this work, TsgcX509Certificate now parses the KeyUsage extension and exposes it via the KeyUsage property plus HasKeyUsageDigitalSignature / HasKeyUsageNonRepudiation helpers, and the new PublicKeyParameters property exposes the raw AlgorithmIdentifier parameters TLV (the named-curve OID for EC certificates).

WideString overloads for Delphi 7

For callers passing non-ACP text (Polish KSeF, Greek myDATA, Bulgarian Peppol, etc.), the public signing and verification API now exposes WideString overloads on TsgcXAdESSigner.SignXML, SignXMLDetached, SignXMLEnveloping (and the matching methods on TsgcDocumentSigner and TsgcSignatureVerifier). This guarantees lossless Unicode in/out on Delphi 7 — no ACP round-trip — and is equivalent to the string overloads on Delphi 2009+.

Conformance and reliability fixes

The bug-fix batch in 2026.5 closes a long list of XAdES / PFX / verifier issues uncovered against live tax-authority endpoints.

Upgrading

2026.5 is a drop-in upgrade for existing 2026.4 projects. The single behavioural change to watch for is TsgcDocumentSigner: code that relied on it emitting plain XML-DSig for the AdES profiles will now correctly produce XAdES — this is what the tax authorities asked for, but if your integration test was pinned to the legacy output you will need to refresh the golden files.

Customers with an active subscription can download the new build from the customer area. Trial users can grab the updated installer at esegece.com/products/sgcsign/sgcsign-download.

Questions, feedback or migration help? Get in touch — you will get a reply from the people who wrote the code.