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):
| Profile | Country | Level | C14N | TSA | OCSP |
|---|---|---|---|---|---|
spEmploymentDE | Germany | B-LT | Exclusive | Yes | Yes |
spEmploymentIT | Italy | B-LT | C14N 1.0 | Yes | Yes |
spEmploymentES | Spain | B-T | Exclusive | Yes | No |
spEmploymentFR | France | B-T | Exclusive | Yes | No |
spEmploymentPL | Poland | B-T | Exclusive | Yes | No |
spEmploymentAT | Austria | B-LT | Exclusive | Yes | Yes |
spEmploymentBE | Belgium | B-LT | Exclusive | Yes | Yes |
spEmploymentPT | Portugal | B-LT | Exclusive | Yes | Yes |
spEmploymentNL | Netherlands | B-T | Exclusive | Yes | No |
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:
- GitHub Actions — composite Action with hash-only Authenticode signing.
- Azure DevOps — native task with secure-file integration.
- Jenkins — declarative pipeline DSL plus shared library.
- Docker — Windows Server Core image plus a
docker-composefile. - Helm — Kubernetes chart for high-availability sgcSign Server.
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.
TsgcDocumentSignernow properly produces XAdES for the AdES profiles. Internally it delegates toTsgcXAdESSignerfor thesfXAdESpath, and raises a clear error forsfPAdES/sfCAdES(use the dedicated signers). A new publishedFormat: TsgcSignatureFormatproperty (defaultsfXAdES) makes the choice explicit. Previous versions emitted plain XML-DSig regardless of profile, which national e-invoicing services rejected.TsgcPFXKeyProvidergains a new publishedHashAlgorithmproperty (defaulthaSHA256), andTsgcXAdESSignernow pushes the active profile's hash into PFX providers. FacturaeB2B-signed PFX-backed invoices are now correctly RSA-SHA1, fixing the FACe INVALID_INVOICE-122 «los datos de la firma no son correctos» rejection.TsgcPFXKeyProvidernow supports modern P12 files:PKCS12_PREFER_CNG_KSP, multi-cert iterate-and-probe, two-stage acquire (ONLY_NCRYPTthenPREFER_NCRYPT) and CNG signing viaNCryptSignHash.- XAdES KSeF / ETSI conformance — V1
SigningCertificatewrapper, conditionalSignaturePolicyIdentifieremission, decimalX509SerialNumber, single-buildSignedProperties(clock-race fix), explicit exc-c14n transforms on theSignedPropertiesreference, and a newSignatureParentElementproperty.TsgcSignatureVerifiernow resolvesURI=#<Id>by element-Id lookup. - X.509 extension parsing — the v3
[3] EXPLICIT Extensionstag content was being double-wrapped, silently skippingKeyUsage,ExtendedKeyUsage, AIA, CDP, SubjectAltName and BasicConstraints on every certificate. Fixed. - Self-closing XML tags —
ExtractFullElementnow handles<ds:DigestMethod Algorithm="…/sha1"/>correctly. Previous versions defaulted to SHA-256, breaking FacturaeB2B verification with "Digest length mismatch for Reference 0". - Inclusive C14N fallback —
TsgcSignatureVerifierapplies implicit inclusive C14N to fragment / empty-URI references that omit an explicit transform, per XML-DSig §4.3.3.2. Fixes "Digest value mismatch" on KeyInfo and body references in inclusive-C14N profiles (FacturaeB2B). - PEM hardening — Unicode
ReadFileContentfix, two-step PKCS#8 decode,AT_KEYEXCHANGEkeyspec, GUID-suffixed CSP container, native encrypted PKCS#8 (PBES2 / PBKDF2 / AES-CBC) via BCrypt,LoadCertificateOnlyand EC marker recognition. - Design-time housekeeping — all nine signer / verifier components now auto-clear linked references via
Notification(opRemove), eliminating dangling pointers when a key provider or TSA client is deleted from the form. - Build hygiene — W1000 (UTF8Decode) in
sgcSign_ASiCfixed via a{$IFDEF UNICODE} UTF8ToStringfallback; H2077 / H2219 dead-code warnings cleaned up insgcSign_XAdESandsgcSign_TrustList.
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.
