sgcSign release notes

Every public release of sgcSign, newest first. Each version lists what was added, what was fixed and anything that changes behaviour, exactly as it is written in the history file that ships with the product.

sgcSign product page · Download

sgcSign 2026.9.0 Latest

  • 2026.9.0: 2026 September
  • NewCertificate lists now carry the SHA-1 thumbprint, the NIF, the serial number, the issuer and the validity dates, the same way for the Windows certificate store, a PKCS#11 token and a PFX file, and can leave out expired certificates and those without a private key. The thumbprint can be passed straight to SelectCertificateByThumbprint, and a new EnumerateCertificateList returns the same information as objects instead of text. The call without parameters is unchanged. Requested by a customer, thank you.
  • NewPKCS#11: a multi-slot card, common with Polish qualified-signature cards that put separate certificates behind separate PINs, can now be inventoried without any PIN. EnumerateCertificateList(aSlotIndex, aFilters, aLogin) reads one slot and EnumerateCertificateListAllSlots reads them all, each entry recording the slot and token it came from, and a new TokenSlotCount reports how many slots actually hold a token, which is the range to address. Requested by a customer, thank you.
  • NewKey providers: new GetIssuerCertificate and GetCertificateChain calls find the certificate that issued the one you are signing with, and the whole path above it. The match is checked cryptographically rather than by name, so an authority that has changed its signing key is not confused with its predecessor. Requested by a customer, thank you.
  • NewKey providers: new IssuerLookup and IssuerFiles properties decide where the issuing certificate is looked for. Most qualified signature cards carry only your own certificate, so the Windows certificate store is now searched as well by default, iluLocalStore searches PEM or DER files you ship with your application, and iluAIA downloads it from the address inside the certificate, which is off by default. Requested by a customer, thank you.
  • NewPAdES: two new profiles. spPAdESBasicT signs with just an embedded timestamp and no revocation data. spPAdESDocumentArchive adds an archive timestamp on top of the long term profile, covering the whole document including its revocation data, so the file stays checkable once the first timestamp's own validity window has passed. Requested by a customer, thank you.
  • NewPAdES: a new CRLFiles property, matching the one XAdES already had, embeds revocation lists you supply yourself, for the authority whose revocation lives in the list issued by its own root. When OCSPClient is assigned and IssuerCertificate is left empty, the issuer is now found automatically. Requested by a customer, thank you.
  • NewCertificates: the subject and the issuer now report every attribute they carry, not just the seven the parser recognised, and the postal address is decoded into readable lines. Any attribute can be read by its OID with GetSubjectAttribute and GetIssuerAttribute, and the full list, in order, through SubjectAttributeCount, SubjectAttributeOID and SubjectAttributeValue. Requested by a customer, thank you.
  • NewTSA: timestamp requests can now be signed, which some qualified authorities, the Polish ones in particular, require. Set RequestFormat to trfCMS and assign a KeyProvider, SignOptions exposes the parts that differ between authorities, and OnBeforeSendRequest and OnAfterReceiveResponse hand you the exact bytes sent and received. The default shape matches a request accepted by PWPW Sigillum's TSA, set SignOptions.IncludeSignedAttributes for an authority expecting the more common form. Existing code keeps sending a plain request. Requested by a customer, thank you.
  • NewAuthenticode: extra certificates can now be embedded in the signature, the same thing signtool /ac does, so a kernel-mode driver signature can chain to the Microsoft Code Verification Root through its cross-certificate. Add them with AddCertificate and AddCertificateFromFile on TsgcAuthenticodeSigner, and ClearCertificates empties the list. They flow into every nested signature, and adding nothing leaves the signature byte for byte what it was. The signing server takes an add_certs field and the CLI a repeatable --add-cert option. Requested by a customer, thank you.
  • NewSignature verification can now be given trust anchors, and it builds and checks the certificate chain. Until now the verifier took the signing certificate out of the document it was checking and confirmed that key had signed that document, which proves only that whoever wrote the document also wrote the signature in it. New TrustedCertificates and TrustedCertificateStore properties say which roots you trust, and RequireTrustedChain, CheckKeyUsage and RequireCompleteRevocationCheck decide how strict the outcome is. An anchor is matched by SHA-256 thumbprint or by verifying under its own key, never by name. A verifier with no anchor returns the verdict it returned before, but the ETSI TS 119 102-2 report no longer says total-passed for a signature that was never chained to an anchor, it says indeterminate with NO_CERTIFICATE_CHAIN_FOUND, so stored reports produced without an anchor need regenerating.
  • NewProxies, proxy authentication and client certificates. Every request the library makes now goes through one transport with a shared HTTPOptions property: the timestamp client, the OCSP and revocation list clients, the EU trust list download and the cloud key providers. It carries the proxy, which can be the system one, none, an explicit address or the one the machine resolves per address, the credentials for a proxy that asks for them, the client certificate, the lowest accepted TLS version and the user agent. Every setting defaults to what those requests did before, and a new OnHTTPRequest event replaces the transport completely for a gateway these settings cannot describe. Requested by a customer, thank you.
  • NewOCSP: the revocation request now carries a random nonce from the system cryptographic generator and the response is checked against it. A new NonceEnabled property turns the extension off for a responder that refuses it. A response echoing no nonce is still accepted, as RFC 6960 allows pre-produced responses, but one echoing a different nonce is refused.
  • NewEU trust list: a new RequirePinnedPivot property, with LOTLPivotPinned and LastPivotFingerprint reporting the outcome, decides whether the list of trusted lists has to chain to one of the pinned Official Journal pivot fingerprints. The check existed and was called from nowhere, and now runs on every download. The pinned constants shipped are still the documented placeholders, so a miss is reported through LastError until you fill in real fingerprints and turn RequirePinnedPivot on.
  • NewCAdES and PKCS#11 both gain a HashAlgorithm property, defaulting to SHA-256 so existing code produces the same bytes as before. CAdES wrote SHA-256 into every digest algorithm as a literal and PKCS#11 chose its DigestInfo header from the length of what it was handed, so no other digest could be expressed. A card can now sign with SHA-1, SHA-256, SHA-384 or SHA-512 as asked.
  • NewASiC: a new BuildCAdES overload takes a signing callback instead of finished signature bytes. It builds META-INF/ASiCManifest.xml first, hands those exact bytes to your callback and stores what it returns as META-INF/signature.p7s, which is the only order in which the signature can cover the manifest. For ASiC-S, which carries no manifest, the callback receives the data document itself. A new GetCAdESSignedData helper returns the same bytes for callers who prefer two explicit steps.
  • NewAWS KMS and Google Cloud KMS: new SetCertificate and SetCertificateFromFile methods, matching the pair HashiCorp Vault already had, to supply the X.509 certificate that belongs to the key. Both services hand out a bare public key, and there was no way to tell either provider which certificate to embed.
  • NewServer: an Authenticode signature can now carry more than two nested signatures, and a different certificate for each one. The upload endpoint accepts hash_algorithms, an ordered list such as sha1,sha256,sha384, and providers, an ordered list such as certA:sha256,certB:sha1, up to four entries either way, providers taking precedence and dual_sign remaining an alias for sha1,sha256. This is for shipping one file signed by an expiring certificate and its replacement. Every certificate is checked against the API key's permissions before any signing starts, and the hash digest endpoint gains a matching nest_into field. Requested by a customer, thank you.
  • NewServer: Windows catalog files can now be signed. The upload endpoint accepts catalog as a format, which signs an existing .cat file of the kind makecat produces, so a driver package can be signed the same way a program is. Creating the catalog itself is not included. Requested by a customer, thank you.
  • NewServer: API keys and the users who create them are now isolated per project. A project admin manages the keys in their own project, including creating, enabling, disabling, deleting and setting limits, the same as a full admin but scoped to that project. An admin can assign any user to a project from the Users page. Requested by a customer, thank you.
  • NewServer: API keys can now be enabled and disabled instead of only revoked one way, and deleted outright. Revoke keeps working as an alias for disable, and the per key rate limit and daily quota can now be edited after the key is created.
  • NewServer: a new SessionAbsoluteMaxMin setting caps the total lifetime of an administrator session, twelve hours by default. Every authenticated request pushed the expiry forward by the whole session timeout with no ceiling, so a session that kept being used never ended on its own.
  • NewServer: new server.firewall.forwarded_headers settings, off by default, which recover the real client address when the server runs behind a reverse proxy. The address in X-Forwarded-For or X-Real-IP is only believed when the connection itself arrives from an address listed in trusted_proxies, so a client cannot invent one, and the chain is read from the right, past the number of proxies given in trusted_hops, because the leftmost entry is the one the client supplied. Entries take IPv4, IPv6 and CIDR, so a dual-stack proxy that reaches the back end as ::1 can be written down. Once resolved, that address is what the firewall lists, the audit log, the webhook payloads and the administrator lockout all work from. Requested by a customer, thank you.
  • Newsgcsign CLI: a new --tsa-direct option asks the timestamp server directly from the machine running the CLI instead of going through the sgcSign Server. Pass it together with --tsa. Requested by a customer, thank you.
  • NewServer: the audit log can now be filtered by client address, both in the administration console and in the CSV export it produces. The address was recorded from the beginning and there was never a way to search it, so the one field an operator reaches for after an incident was the one field that could not be queried. A partial address matches from the left, so 203.0.113. selects a range and a complete address selects a single client, and the count behind the pager applies the same filter as the list.
  • NewServer: a new /api/v1/sign/raw endpoint signs a digest you have already computed and returns only the signature value, with no PKCS#7 wrapper, no signed attributes and no timestamp. This is exactly what signtool asks for through its /dlib callback, which builds the Authenticode signed attributes itself and expects back only the signature over their hash, which the existing hash endpoint cannot supply because it builds its own attributes and returns a finished PKCS#7. Since it will sign any digest handed to it, it is off by default and is turned on one provider at a time with allow_raw_sign in that provider's params. Nine of the ten key providers offer it, Certum SimplySign cannot because its service does the hashing on its own side, and it answers 422. Requested by a customer, thank you.
  • FixedSignatures made with a smart card, a USB token or a cloud key were wrong, and CAdES signatures were wrong with everything else. SignData had no written contract and the providers disagreed about whether its argument is the data to sign or a digest of it, so every CAdES signature was RSA over a hash of a hash, rejected on submission by OpenSSL, the EU DSS validator, Adobe and every national e-invoicing gateway, while a card signed without error and produced a file no verifier accepts and four of the five cloud providers could not sign at all. The argument is now the raw bytes and the provider hashes them with its configured digest. CAdES files, and anything signed with a card or a cloud key, should be signed again.
  • FixedEvery PAdES, CAdES, Authenticode, NuGet and RFC 3161 signature made with an EC key was structurally invalid. The standards require the signature value inside a CMS structure to be a DER ECDSA-Sig-Value, and the key providers produce the raw concatenation of r and s, which is what XML-DSig wants, with nothing converting it on the way into CMS, so Adobe, OpenSSL, Windows and every eIDAS validator rejected the result. It went unnoticed because the verifier was wrong in the same direction. P-256, P-384 and P-521 all work now, and the XAdES and XML-DSig paths are deliberately left alone. Files signed with an EC key by an earlier version have to be signed again.
  • FixedAuthenticode: verifying a signed program never checked a signature. Verify pulled the file hash out of the signature, recomputed the same hash and reported that comparison as the verdict, so forging a file that sgcSign called validly signed needed no private key, and the server's verify endpoint answered valid, admitting arbitrary binaries into any build pipeline using it as a gate. Verify now requires the recomputed digest to equal the messageDigest attribute, locates the signer certificate by the issuer and serial the signature names, and verifies the RSA or ECDSA signature over the signed attributes. The result gains HashValid, SignatureValid, CertificateExpired and ChainValidated, so an expired signer certificate is reported without invalidating the signature.
  • FixedRevocation checking did not work. On the signing side an OCSP response was accepted as good after reading a single tag byte, with no signature check and no freshness test, so a recorded reply from before the certificate was revoked, or a hand built unsigned one, was embedded into a long term signature as proof the certificate was good. On the verifying side an embedded response was matched on the serial number alone and used with no signature check, and that block sits outside the signed area, so anyone holding the file could rewrite it to keep a revoked certificate verifying without breaking a digest, while a match of any kind suppressed the live query. A response is now verified before any field is read, the identifier is compared byte for byte, thisUpdate and nextUpdate are enforced with five minutes of skew, and freshness is measured against the signature's own signing time so archived signatures still verify. An incomplete check does not change the verdict by default, and can be made to with the new RequireCompleteRevocationCheck.
  • FixedTSA: a timestamp token was embedded without being checked. The only thing verified was the nonce, and even that exited silently when the token could not be parsed, so a reply carrying an empty structure produced a PAdES-T, CAdES-T, XAdES-T or Authenticode file that reported success and carried a timestamp no validator can validate, a rejection was read as granted, and a correctly signed token covering a different document was accepted verbatim. The status is now read over its whole length, an unparseable token is a hard failure, the hash algorithm and hashed message must equal what was requested, and the signature over the signed attributes is verified.
  • FixedThe EU trust list was downloaded and used without verifying anything at all, and because the member state addresses come out of that same document one substituted list redirects every member state download in a single step, so anyone able to answer for those addresses, or to write into the cache directory, could have their own authority reported as qualified by IsQualifiedAtTime. The signature on the list of trusted lists is now verified before parsing, and each member state list is accepted only when its signing certificate is one of the service digital identities that list publishes for the territory, matched by SHA-256 and never by name. A territory publishing no identity is refused and named in LastError. All 31 member state lists bind by exact thumbprint, for 3,691 services.
  • FixedXML signatures: two ways the verifier could be made to check something other than the part of the document it was reporting on. A ds:Reference of the form URI="#x" was resolved by trying each candidate identifier attribute name in turn, ID first, then Id, then wsu:Id, so an element carrying ID="x" anywhere in the document outranked the genuine element carrying Id="x" that came first. That is signature wrapping, the standard break against SAML assertions and WS-Security messages. Separately, the enveloped signature transform removed the first child element whose local name was Signature and accepted an element in no namespace as one, so forged content could hide inside a business element written as <Signature xmlns="">, and two parallel signatures could neither be verified nor signed correctly. Identifiers are now resolved in a single pass, a duplicate identifier is a hard failure on both sides, and the transform requires the XMLDSig namespace and removes itself instead of the first signature it finds.
  • FixedA malformed file could make the library read or write outside its own buffers. The ASN.1 parser accumulated a declared length into a signed integer with no bound and no overflow test, so an impossible size came back negative and the walk went backwards out of the buffer, while a length working out to zero advance grew memory until the process died. The message builder then copied the issuer name using the length the certificate declared rather than the length present, so unrelated process memory was signed into the signature, which on the signing server means those bytes travelled back to whoever uploaded the crafted certificate. The parser now rejects a length that does not fit the bytes present and stops a walk that is not advancing, the copy sites are bounded, and a program whose security directory overlaps its headers is refused. Well formed input produces byte identical results to before.
  • FixedPAdES: a PDF could be signed with one digest and labelled with another, producing a file that sgcSign reports as signed and that Adobe, the EU DSS validator and pyHanko all reject, with no warning before the document was submitted. Profile.HashAlgorithm was written once in the constructor and never read again, and a key provider shared by two signers on the same form kept whatever the previous signer left on it, so a PDF signed after a Facturae or SAF-T signer was RSA over a SHA-1 digest inside a signature declaring SHA-256. The hash algorithm is now read at every digest site, and the PAdES signer pushes its own digest into the provider immediately before signing and restores the previous value afterwards.
  • FixedPAdES: a reason, location, contact or signer name containing a bracket produced a PDF that readers refuse to open. "Approved :-)" is enough, and so is a European address or a Windows path. On the signing server, where those values arrive as form fields, an unbalanced bracket closes the string early and the rest becomes PDF syntax inside the signature dictionary, which sits inside the range the signature covers, so a request could add a second signing date under a valid signature made with the server's own key. All four values, the certificate name used when no signer name is given and the signature field name are now escaped, extended to carriage return, line feed, tab, backspace and form feed.
  • FixedThe Google Cloud KMS provider could never authenticate, under any configuration. The assertion sent to obtain an access token declared RS256 and was in fact signed with HMAC-SHA256 keyed on the text of the private key, so Google answered invalid_grant and Connect never completed, with an error that reads like a bad service account or a missing role. The assertion is now a real RSASSA-PKCS1-v1_5 SHA-256 signature made with the service account key, accepting both PKCS#8 and PKCS#1 files.
  • FixedPAdES: long term validation did not work. Profile and TSAClient did nothing at all, so spPAdESLTV produced a signature identical to the basic profile with no timestamp and no revocation data, and setting a profile only recorded which one was requested. Once a timestamp was embedded the validation data still carried nothing about it, so Acrobat reported that the timestamp could not be verified. TSAClient now embeds a real timestamp, the new OCSPClient and IssuerCertificate properties add the signing certificate's revocation status, and the validation data carries the whole path of both the signing certificate and the timestamp with the revocation list covering every certificate in them. Reported by a customer, thank you.
  • FixedPAdES: a document signed with an invisible signature, which is the default, opened in Acrobat as "at least one signature is invalid" with nothing listed in the Signatures panel. The signature was correct, the field was never attached to a page, so Acrobat found it but could not place it. Documents whose page keeps its annotations in a separate object had the same problem and are handled too. Reported by a customer with a sample PDF, thank you.
  • FixedPAdES: the signing time was read from the computer clock but written as if it were UTC, so a signature made at 15:00 in Madrid was stamped as 15:00 UTC, two hours early. Both dates now use real UTC.
  • FixedOCSP: the responder address was read from the wrong entry of the certificate. A certificate publishes several addresses in the same extension, one for the responder and one for downloading the issuing certificate, and the code took the first one that merely looked like a web address, so on a certificate that lists the issuer download first, which many qualified certificates do, the request came back as "OCSPClient returned an empty OCSP response". The responder is now selected by its own identifier. Reported by a customer, thank you.
  • FixedXAdES: automatic resolution of the issuing certificate matched by name and authority key identifier alone with no cryptographic check, and silently fell back to whichever certificate was listed first, or to the signing certificate itself, so the revocation data could be built against the wrong certificate. It now uses the same verified match PAdES and the key providers use, can resolve the issuer through the KeyProvider as well as from listed files, and reports a clear error instead of guessing. Delphi and .NET both affected.
  • FixedTSA, OCSP and the EU trust list: the Timeout property was never applied to the connection and the trust list download had no timeout at all, so a server that went quiet held the call for the system default. An HTTP error page was also handed to the parser as if it were a response, reported as "Invalid TSA response: expected SEQUENCE" or a parse failure, and the status is now checked first and reported as it is. The TSA request nonce came from a generator reseeded from the system clock, so two requests in the same instant could carry the same predictable nonce, and it now comes from the system cryptographic generator.
  • FixedAuthenticode: a file signed with no timestamp server assigned still showed a signing time in its properties, with no timestamp certificate behind it, which could look like a fake timestamp. It is no longer written unless the new IncludeSigningTime property is turned on, and verifying a file now reports the real timestamp date and who issued it. Reported by a customer, thank you.
  • FixedPKCS#11: a login that failed, or was intentionally skipped, could leave the connection to the card open, after which every later certificate listing reported the first slot whichever slot was requested. Listing certificates now opens a read-only connection, which is less likely to be refused while another application also has the card open. EnumerateSlots and SlotIndex also numbered slots differently as soon as one reader was empty, and they agree now.
  • FixedWindows certificate store: the certificate list reported the subject and issuer as a short display name and the dates in local time, while the same list from a PKCS#11 token or a PFX file reported the full distinguished name and UTC, and it left the NIF empty for a qualified company seal. All three now report the same thing, with SubjectCN and IssuerCN for the short name and NotBeforeLocal and NotAfterLocal for local time.
  • FixedCertificates: a qualified company seal certificate reported no tax number. These certificates carry no serial number attribute at all and keep the company identity in the organization identifier as VATPL followed by the NIP, which until now only the KSeF helper knew about. GetNIF now falls back to it. Reported by a customer, thank you.
  • FixedCloud key providers: when the service rejected a request, the explanation it sent back was decoded one byte per character, so the message was unreadable exactly when it was most needed. AWS KMS, Azure Trusted Signing, Google Cloud KMS and HashiCorp Vault were affected.
  • Fixed.NET: signatures could not be verified by other software. The issuer name inside the signature was wrapped one time too many, so no reader could match the signature to the certificate that made it and verifiers reported the signer as unknown. This affected PDF, CAdES and Authenticode signatures produced by the .NET version, so documents signed with an earlier .NET version should be signed again. The Delphi version was never affected.
  • FixedServer: an XML document signed through the server was signed over the wrong bytes, and half of what it did sign was uninitialised memory. The helper that turns the uploaded body into text sized the destination in characters and copied that many bytes, so it allocated twice the space it filled, the second half being whatever the memory manager had last left there, which in this process is the heap of a daemon holding PFX passwords, PKCS#11 PINs and decoded private keys. The XAdES signer signs what it is handed without parsing it, so the caller received HTTP 200 and a genuine signature over a document that is not the one they uploaded. The same helper read the Google Cloud service account file, which is why a provider configured by file path never came up.
  • FixedServer: an administration page or a CSV export could return blank rows and then bring the process down. Every list query sized its result array from the record count before reading it, and the database layer fetches fifty rows at a time, so everything past the fiftieth row was written outside the allocated block. Exporting an audit log with more than fifty entries did it every time, usually surfacing as an access violation in a later, unrelated query. All eight list queries now grow their array as they read.
  • FixedServer: under concurrent use the sign and verify endpoints could return a signature over another request's file. The uploaded file was located by scanning a shared temporary directory and taking whichever file was newest, so under load a request could pick up a different request's upload, or a file the web server still had open, which showed up as an occasional error saying the file was in use. Every request now unpacks into a directory of its own, and leftover temporary files are cleaned up, which they never were.
  • FixedServer: the tamper evident audit log broke itself under ordinary load. Each entry reads the previous entry's hash, computes its own over it and inserts, and those were separate calls with the storage lock released between them, so two requests logging at the same moment both stored the same previous hash. The chain then reported a break at that entry for the life of the database, and since the verifier stopped at the first break everything after it was outside the verified region. The read, the hash and the insert now happen under one hold of the lock, and the verifier, which was never called from anywhere, is reachable at /admin/audit/verify.
  • FixedServer: demoting or deleting an administrator did not affect the session they were already using. The role was copied into the session at login and every later permission decision read that copy, so an account revoked in the morning could still create API keys, delete projects and change other users' passwords in the afternoon, while the console reported the change as successful. A role change, a password change and an account deletion now all end every session belonging to that account. The routine that removes expired sessions was called from nowhere, so the session list also grew by one entry per login, and the metrics timer now calls it.
  • FixedServer: the per project isolation this release introduces had two holes in the administration console. Any authenticated session, including an operator or an administrator of a different project, could open /admin/audit or download /admin/audit.csv and receive the complete history of every project, and could read every non secret provider setting, the AWS ARNs, the Azure tenant and client identifiers, the Vault address and key name, and the file paths of PFX, PEM and PKCS#11 material. A project administrator could also approve or reject a pending signing request belonging to another project simply by posting its number, and those numbers are sequential, so four eyes control could be defeated from a different tenant. The audit routes are now limited to administrators and project administrators and scoped to the caller's own project, taken from the session and not from the request, the providers page is limited to full administrators, and a decision on another project's approval is refused and logged as denied.
  • FixedServer: the theme switcher took the return address out of the query string and put it into the Location header without checking it, and that route is deliberately reachable with no session so the theme can be changed on the login page. Query parameters are already URL decoded by then, so a carriage return and line feed inside the value split the response into extra header lines, and anyone able to reach the port could make the server emit a Set-Cookie of their choosing, fixing the session cookie of an administrator on the console that drives code signing. Without the line breaks the same route was a plain open redirect wearing the signing server's own hostname. A redirect target is now accepted only when it is a server relative path beginning with a single slash and carrying no carriage return or line feed, and that check lives inside the redirect helper itself.
  • FixedServer: a dual signed PE file's first signature, the SHA-1 one, was rejected by Windows as invalid while the nested SHA-256 signature verified correctly, because the signature declared SHA-1 and the key provider hashed with SHA-256 regardless of what was requested. Every SHA-1 Authenticode signature was affected, not only the dual signed ones. Cloud and HSM key providers, which cannot be told which digest to use, now refuse a SHA-1, SHA-384 or SHA-512 request with a clear error instead of producing a signature that looks correct and is not. Reported by a customer, thank you.
  • FixedServer: an error reply whose message contained a double quote was not valid JSON, so a client trying to read the error failed to parse the reply instead. The verify reply and the webhook payload both carry the certificate subject, which can legitimately contain quotes and backslashes. Text in replies is now escaped properly.
  • FixedServer: the database was used from several request threads at the same time with nothing to keep them apart, which caused access violations inside the SQLite library, transaction errors and now and then a corrupted query. The first failure left the connection unusable, so the server carried on failing until it was restarted. Database access is now serialised, one request at a time.
  • Fixedsgcsign CLI: the signing certificate's name printed as question marks when it held non-Latin characters, Chinese in particular, while the verify command printed the same name correctly. The name travels back from the server in a response header, which can only carry plain ASCII. The server now encodes that header and the clients decode it. The .NET client was affected the same way and is fixed too. Reported by a customer, thank you.
  • FixedBase64 text was decoded into the wrong bytes, silently, whenever it arrived in the shape it normally arrives in. Anything the decoder did not recognise was treated as zero bits rather than refused, and that includes the line breaks that PEM files, XML signatures and HTTP payloads are full of, so a certificate wrapped across lines came back longer than it should and full of rubbish with no error at all. The same happened to the URL safe alphabet several qualified authorities return, which turned their signatures into corrupt bytes of exactly the right length. Line breaks and spaces are now skipped, the URL safe alphabet is understood, and anything else is refused with a clear error.
  • FixedA crafted ASiC container could make the library read outside its own memory. The offsets and sizes in a zip index are unsigned numbers supplied by whoever built the file and they were read into a signed type, so a large value became negative and the check meant to keep the read inside the file passed. Every one of those values is now held in a type that can represent it, and every bounds test is written so it cannot overflow. Legitimate containers are unaffected, checked against a set of real ASiC, Office, NuGet and VSIX files.
  • FixedA crafted program file could crash the signing service. The Authenticode hasher worked out how much of the file to hash by subtracting two unsigned numbers with no check that the result made sense, so a file with deliberately impossible header sizes produced a length of about four gigabytes over a small buffer. A second form of the same fault was quieter and worse: a section positioned to wrap around the end of the address space hashed bytes from before the buffer and returned a digest, so the signature covered the wrong bytes and nothing reported it. Both are refused now, and a program whose stated header size is smaller than its own headers is rejected when it is opened.
  • FixedA program or NuGet package signed with an EC key was reported by Windows as not signed at all. The signature structure named RSA whatever key had actually signed, so signtool could not pair the algorithm with the signature and answered "No signature found". The algorithm is now taken from the key that signed. Files signed with an EC key by an earlier version have to be signed again, and signatures made with an RSA key are byte for byte what they were.
  • FixedPAdES: a reason, location, contact or signer name containing anything outside plain English was written into the PDF one byte per character, so accented and non-Latin text arrived mangled and Polish, Cyrillic or Chinese metadata was unreadable in the Signatures panel. Text is now encoded the way the PDF specification defines. The visible signature stamp also never declared which encoding it used, so accented characters in a stamp drew the wrong letter even before this, and it does now. Plain English values produce exactly the bytes they produced before.
  • FixedA document signed with a cloud or smart card key could be signed with a different digest from the one the file declares. The check that refuses a digest such a key cannot produce existed only for Authenticode, and the XAdES, XML-DSig and SAF-T PT signers asked the key the same way without it, so with a cloud key the request was ignored in silence. The concrete case is the Portuguese SAF-T PT invoice, where the law requires SHA-1 and the file was signed with SHA-256, non compliant in a way only discovered on submission. All three now refuse with a clear error naming the provider.
  • FixedCloud key providers returned whatever the service sent back without checking it was a signature at all, and the PDF, XAdES and XML-DSig signers did not even check it was not empty. A truncated or corrupted answer therefore became a signed PDF carrying an empty signature, reported as success, which no validator accepts. All six providers now require the signature to be exactly the size the key produces, and the three signers refuse an empty one.
  • FixedData that was not a certificate was accepted as one. Anything shaped like a DER sequence passed, including a bare public key and a revocation list, and produced a certificate with an empty subject, issuer and serial number rather than an error, after which two such certificates compared as each other issuer. The structure is now checked properly before it is accepted. Every certificate in the Windows stores still parses, including the version 1 ones that need special care.
  • FixedXAdES: the signing time, the signing certificate digest and the signature policy were read out of the file and reported as signed without any check that the signature covered them. Anyone holding a validly signed document could add a second properties block ahead of the genuine one and have its signing time reported as authentic. Those properties are now found through the reference that covers them, and a signature that does not cover them is invalid.
  • FixedRevocation lists were believed without being checked. Whatever a distribution point returned was embedded into a long term signature as proof of revocation status, the only test being that the download was not empty, so an error page or a captive portal response became evidence. The lookup that answers whether a certificate is revoked matched serial numbers alone, never verifying the list signature, its dates, or that it came from the right authority, so an unsigned or out of date list confidently answered "not revoked". A list is now verified before it is believed or embedded, and a new CheckRevoked reports "cannot tell" as an answer of its own instead of returning the same value as "not revoked".
  • FixedSigning with a PEM or PFX key left a copy of the private key in the Windows key store, permanently, and nothing ever removed it. One container per signing operation, so a server signing continuously accumulated them without limit, and a count on one development machine found 2,311 of them. Saving to a P12 file left an exportable copy behind as well. Both providers now keep the key in memory only, and where the system will not allow that they delete what they created, including when signing fails part way through. Installations upgraded from an earlier version still hold the old containers and have to have them removed separately.
  • FixedA crafted private key file could make the library read outside its own memory, or hang forever. The length check in the PEM reader added two numbers that could overflow, so an impossible length passed as valid, and one shape of the same fault left a loop advancing by nothing at all, spinning at full CPU and allocating until the process died. One key file was enough, anywhere a key file is accepted, including the server setting and the command line client. Every real key file still loads, checked across RSA, EC, encrypted and unencrypted forms.
  • FixedServer: checking an administrator password wasted a quarter of a second, because the password derivation opened and closed a cryptographic provider two hundred thousand times, once per round. It opens one and reuses it now, taking the same check from 252 milliseconds to 8. Stored passwords are unchanged and nobody has to set a new one. The login page also had no limit on attempts, giving an attacker both unlimited guesses and an easy way to exhaust the machine, and it now locks an account or an address after five failures in five minutes. Every failed login takes the same time and returns the same page whatever the reason, so the limit cannot be used to discover which accounts exist.
  • FixedServer: two requests arriving at the same moment could be given the same temporary file name, and one request was then signed over the other request document. The name was built from the clock and a weak random number, and it now comes from a unique identifier, with the file created in a way that fails rather than overwrites if the name is somehow taken. Reproduced before the fix with eight threads, which collided.
  • Fixedsgcsign CLI: an option given without a value silently swallowed the option that followed it and the run reported success. Signing with --out followed by --verbose wrote the signature to a file called --verbose and exited with code 0, so a build pipeline was told the signing had worked while shipping an unsigned file. Every option taking a value now refuses one that looks like another option, and fails naming it. Two more paths that reported success on failure are fixed as well: an unrecognised hash name quietly fell back to SHA-256 while telling the server something different, and an empty reply from the server produced an empty output file, which with no --out given overwrote the file being signed.
  • FixedEvery outbound request the library makes could be used to exhaust the memory of the machine making it. The response body was read in a loop that appended until the server stopped sending, with no ceiling and no setting to impose one. That matters because a revocation list address and an issuer certificate address are read out of the certificate being checked, so an attacker who supplies a document chooses where those fetches go. A new maximum, 64 MB by default, is applied as the bytes arrive rather than after they have all been read, so an endless response is cut off rather than collected first. The number was chosen by measuring: the largest revocation list any public authority publishes is under 11 MB and the largest EU member state trusted list is under 6 MB. Set it to 0 for the old behaviour.
  • FixedA crafted signature container could make the library attempt an allocation of several gigabytes. Each entry declares how large it will be once decompressed, and that figure was believed and reserved before anything was read. A small file could therefore claim four gigabytes per entry. Decompression now grows its buffer as it goes and stops as soon as the real output passes a ceiling, and an entry whose declared size is already past it is refused before anything is reserved. The ceiling is generous, 256 MB per entry, and no legitimate container comes near it: the largest expansion measured across every sample in the tree is under 24 to 1 where the limit is 200 to 1.
  • FixedThe Authenticode hash covering a program file was computed wrongly for two layouts that occur in real software, so a validly signed file was reported as modified, and a file signed by sgcSign carried a hash Windows rejects. The trailing part of the file was located by adding up section sizes, which is only correct when the sections sit back to back. Programs built with the GNU linker leave a gap, and programs compressed with UPX overlap, so bytes were left out of the hash and others were counted twice. The file is now walked once from start to finish whatever its layout. Measured across 10,458 signed programs on one machine, 552 were affected. Anything already signed with one of those layouts has to be signed again.
  • FixedA certificate store entry that could not be read stopped the whole store being read. One unparseable entry abandoned the enumeration, so a trust store named in the configuration contributed nothing at all, and every verification then reported that no trusted chain could be built. The reason pointed at the certificate chain rather than at the store, which is where the real problem was. Unreadable entries are now skipped and the rest of the store is returned, and a new SkippedCertificates count tells an empty store apart from a store full of material the parser cannot read.
  • FixedSignatures made with an EC key declared the algorithm in a form the standard forbids. RFC 5758 requires the parameters field to be absent for the ECDSA algorithm identifiers, and PAdES, CAdES and the CMS format timestamp request all wrote an explicit NULL there. Authenticode and NuGet were corrected earlier in this release, so the product disagreed with itself. Files already signed with an EC key stay verifiable, because that field sits outside the signed data and never entered the hash, but they have to be signed again to conform for a verifier that enforces it.
  • FixedThe CSC key provider ignored every proxy, client certificate and TLS setting. It built its own HTTP request instead of using the shared transport the other providers use, so nothing set through HTTPOptions reached it and the interception event never fired. A customer behind a proxy, or one required to present a client certificate to their qualified authority, could not make it work and there was nothing in the API to say why. It now uses the same transport as every other provider. The bytes sent are unchanged apart from the user agent, which is now the product one and can be set.
  • FixedLicense tool: an option given without a value silently swallowed the option that followed it, and a license was issued against the wrong parameters with no error. The expiry date could end up set to the literal text of the next option. The tool now refuses a value that looks like another option and names the option that is missing one, understands the --option=value form, and examines the last argument on the line, which it previously ignored. A misspelled option, a stray argument and a non numeric limit are now errors rather than being dropped in silence.
  • FixedServer: the signing endpoints refused base64 in the shapes it usually arrives in. The URL safe alphabet that several qualified authorities return, a value wrapped across lines the way it appears in a PEM file or an XML document, and a value without padding were all rejected, although the library itself accepts all three. The endpoints now use the same decoder as the rest of the product. Nothing that was accepted before is refused now.
  • FixedCertificates: a malformed certificate could produce a public key fingerprint computed over the wrong bytes. The public key was taken from its usual position before that position had been checked to hold a key at all, so on a malformed certificate the extensions could be fingerprinted instead. The value looked entirely plausible and identified nothing, which matters because that fingerprint is what key pinning compares. Nothing is captured now unless it really is a public key.
  • FixedServer: when a webhook could not be delivered because the endpoint certificate could not be validated, the audit record and the console both reported it as a socket error, mentioning neither TLS nor a certificate nor which setting would fix it. Deliveries now report what actually failed, naming the certificate problem, the certificate itself, what it was checked against and the setting that resolves it.
  • FixedServer: a value saved through the console did not survive being read back. Text was written with JSON escaping and read without it, so a Windows path typed as C:\certs\ca.pem came back with its separators doubled, and any value holding a quotation mark, a tab or a line break was corrupted, a little further each time it was saved. Reading and writing now agree. A configuration file holding native Windows paths is repaired automatically on the first start after upgrading, with the original kept beside it.
  • FixedXAdES: a signature could be reported as valid without anything in it committing to which certificate signed it. The standard requires a signing certificate reference in the signed properties, and its absence was reported as a note rather than treated as a fault. A new RequireSigningCertificate setting makes it a fault. It is off by default, so nothing that verifies today changes unless you turn it on.
  • FixedRevocation lists published by a separate authority, which the standard permits and several government infrastructures use, could not be used at all, and neither could a list or an OCSP response signed with RSASSA-PSS. Both were reported as giving no answer rather than a wrong one, but the effect was that no revocation answer was available. Both now work, and PSS is understood for certificate chains as well. Ed25519 and the GOST algorithms are still not supported and still report that no answer is available.
  • FixedAuthenticode: a file whose digest algorithm the library does not implement was reported as having a hash mismatch, which says the file was modified. The truth was that it could not be checked at all, because any unrecognised algorithm was quietly treated as SHA-256 and a hash of the wrong size was compared. Such a file is now reported as using an unsupported algorithm, and the algorithm is named. Files affected in practice are old ones signed with MD5, which Windows also refuses.
  • FixedCatalog files could not be signed with a complete certificate chain. The option that attaches the intermediate certificates was only read by one of the two signing routes, and not by the one that handles .cat files, so a catalog signature could not chain up to the Microsoft Code Verification Root. It now works for catalogs as it already did for programs. Reported by a customer, thank you.
  • FixedCertificates attached to a signature were written in the order they were supplied rather than in the order the encoding rules require. Windows refused to read a catalog signed this way at all, reporting that it contained no signature, while the same certificates inside a program file were accepted. Any catalog signed with extra certificates by an earlier version has to be signed again. Signatures carrying no extra certificates are unchanged.
  • FixedServer: on the provider page, the name and kind of an existing provider were shown in boxes that looked editable but silently discarded anything typed into them. Both are deliberately fixed once a provider is created, because the name is what every API key permission, command line option and configuration entry uses to refer to it. They are now shown as plain values so that is visible before you spend time on it. The form for a new provider is unchanged. Reported by a customer, thank you.
  • FixedA timestamp request in the CMS signed format could carry a certificate set that is not valid DER. The signing certificate and its issuer were written in the order they were collected rather than in the order the encoding rules require, so an authority that checks strictly is entitled to reject the request. It affects a request made with SignOptions.IncludeChain turned on, a key provider that can resolve an issuer, which the PFX, Windows certificate store and PKCS#11 providers all can, and RequestFormat set to trfCMS, the signed format several qualified authorities ask for. The same ordering rule was corrected for signatures earlier in this release, but the timestamp client carried its own copy of the code and was missed. A request that carries a single certificate is unchanged, byte for byte.
  • FixedServer: the administrator login lockout counted failed attempts per source address, and behind a reverse proxy every administrator arrived from the same proxy address, so five failures from one attacker locked every administrator out for the whole lockout window. It counts against the real client address now, which needs server.firewall.forwarded_headers configured for the proxy in front.
  • FixedServer: the REST API read X-Forwarded-For by itself with no check on who sent it, so any client could write an address of its choosing into the audit trail and into the webhook payloads, while the administration pages ignored the header entirely and recorded the proxy address instead. Neither reads the header now. Both take the address the firewall resolved, which comes from the header only when the connection arrives from a configured trusted proxy.
  • FixedServer: the brute_force settings under server.firewall did nothing at all. The values were read from the configuration file, validated, applied to the firewall and shown in the administration console, and no failed attempt was ever reported to it, so no address was counted and none was ever banned. A server configured for brute-force protection has had none since the setting appeared in 2026.6.0. Failed administrator passwords and invalid API keys are now counted against the address they came from, a request carrying no key at all is deliberately not counted because an absent header is not a guess, and with server.firewall.forwarded_headers configured the ban falls on the client rather than on the proxy in front of it.
  • BreakingThere is now a single TsgcX509Certificate. The library declared three different classes under that name, and the one the certificate lists were built from was a small copy carrying ten fields, so reading anything else about a listed certificate meant parsing its raw data again through a different class of the same name. The lists returned by EnumerateCertificateList now hold the real certificate class, and TsgcX509CertificateList moved to sgcSign_X509 alongside it. Code that lists certificates needs sgcSign_X509 added to its uses clause, and in C++Builder the matching sgcSign_X509.hpp include. Reported by a customer, thank you.
  • BreakingASiC-E CAdES containers built by earlier versions carry no cryptographic link at all between the signature and the documents inside them. Every ds:DigestValue in META-INF/ASiCManifest.xml was written as an empty element, and the signature bytes were a parameter produced before the manifest existed, so anyone holding such a container can replace any document in it and repack the zip. The manifest now carries real base64 SHA-256 digests and an empty document name is refused. The old BuildCAdES that takes finished signature bytes still compiles, now marked deprecated, and still cannot produce a bound container, so callers producing ASiC-E have to move to the new overload that takes a signing callback. Containers already issued should be reissued.
  • BreakingTSA: a timestamp token is now accepted only when the signing certificate carries id-kp-timeStamping as a critical extended key usage, which is what RFC 3161 section 2.3 requires. An authority that marks it non critical will be refused where it was accepted before.
  • BreakingAn OCSP response or an RFC 3161 timestamp token signed with RSASSA-PSS is now refused rather than accepted, because the shared algorithm table used by the new checks does not cover PSS. It appeared to work before because nothing was being verified. Support for PSS in that table is tracked separately.
  • BreakingHashiCorp Vault: an ECDSA or Ed25519 transit key is now refused at Connect with a clear error, and only rsa- key types are accepted. Those keys were admitted before and then signed as if they were RSA, so a key that appeared to work was producing signatures no verifier accepts. Supporting them properly is a feature request rather than a fix.
  • BreakingKey providers: a credential typed into the Object Inspector is no longer written into the .dfm. Fourteen properties across eleven units are now marked as not stored, among them the AWS secret access key, the Azure client secret, the Google Cloud service account JSON, which carries the RSA private key itself, the Vault token, the CSC and Certum passwords, PINs and secrets, the PFX and PEM passwords, the PKCS#11 PIN and the proxy password. A design time value used to reach the .dfm in version control, the compiled executable as a plain text resource, and any crash dump. The properties stay visible in the Object Inspector and assignable from code, and an existing .dfm still loads, but the value it holds will disappear the next time the form is saved.
  • BreakingServer: the server.listen setting now binds the listener to the address you give it. It was parsed, defaulted, printed on the startup banner and never applied to anything, so a server configured to listen on 127.0.0.1 was in fact listening on every interface while the console said otherwise, and the whole network could reach /admin/login and the signing endpoints directly, skipping the reverse proxy and its client certificate check. A deployment that was quietly reachable from elsewhere becomes unreachable on upgrade, which is what the configuration was asking for. An address that is not a valid literal is now rejected at startup. The trial and community configuration files still say 0.0.0.0 with TLS disabled.
  • Breakingsgcsign CLI: the indy transport no longer connects without validating the server certificate. It never validated it. There was a branch for --insecure and a branch for --cacert and nothing in between, so the default accepted any certificate the far side offered and printed nothing, and since every request carries the API key in a header, anyone on the path collected a credential that authorises signing. The default path now looks for trust material in SSL_CERT_FILE and SSL_CERT_DIR, then for cacert.pem, ca-bundle.crt, ca-certificates.crt or curl-ca-bundle.crt beside the executable, then in the usual /etc/ssl and /etc/pki locations. When it finds nothing it raises an error naming --cacert and --insecure instead of connecting unvalidated, so on Windows --transport indy with no --cacert and no cacert.pem beside the executable now fails where it used to connect. WinHTTP, the transport chosen automatically on Windows, was never affected.
  • BreakingServer: every administration action that changes something now requires a form post carrying a one time token, and eleven of them that could be triggered by a plain link refuse one. Until now the only protection was a browser setting, so any page an administrator visited while logged in could delete an API key, change a user password or approve a pending signing request just by loading an address. Scripts that drove the console by fetching addresses such as /admin/users/delete?id=2 will stop working, and a script that posts to the console has to read the token out of the page first.
  • BreakingServer: webhook deliveries over HTTPS now check the certificate of the address they are sent to, and refuse to deliver when it cannot be validated. They never checked it and there was no way to turn checking on, so signing event data went to whoever could intercept the connection. A new verify_tls setting turns the check off for one webhook and a new ca_file names the authority for an internal endpoint. A list of public certificate authorities, cacert.pem, is now installed beside the server so this works without any configuration; on Windows there is usually no system list available to this check, and without that file deliveries to public addresses would stop as well. If you run the server from a copy you made yourself rather than from the installer, copy cacert.pem alongside it, or set SGCSIGN_WEBHOOK_CACERT. An endpoint whose certificate does not match the address it is reached at is now refused too.
  • BreakingServer: the max_upload_mb setting is now the real limit on how much a request can send, and it defaults to 64 MB. It was never applied to a request that did not declare its length up front, which any client can choose, and the underlying transport was imposing its own 64 MB limit regardless of what the setting said, so the setting was ignored in both directions. A server left on the default therefore accepts exactly what it accepted before. What changes is that a value you set yourself is now obeyed: if you had raised max_upload_mb above 64 and wondered why larger uploads were still refused, they now work.
  • Breakingsgcsign CLI: a value beginning with a dash can no longer be given after a space, because it cannot be told apart from a mistyped option. Write --option=value instead, or put the value after a bare --, which is now understood as the end of the options. In practice this affects the free text options only, such as --desc, --reason and --location.
  • BreakingXAdES: a signature whose signed properties are not covered by a reference carrying the type the standard defines is now invalid rather than valid. Signatures made by sgcSign have always carried it. A signature from another product that leaves the type attribute out, or that points at those properties in an unusual way, is now refused.
  • BreakingA revocation list signed with RSASSA-PSS, Ed25519 or a GOST algorithm is now reported as unusable rather than believed, because the table of algorithms these checks share does not cover them, and so is a list issued by a separate revocation authority rather than by the certificate own issuer, which the standard does permit. Neither gives a wrong answer, both report that no answer is available. The IsRevoked call that is given no issuing certificate now raises an error rather than answering "not revoked" for a list it has no way to check.
  • BreakingThe PFX key provider now keeps the private key in memory rather than in the Windows key store, on Windows 8 and later. Anything that expected to find the key in the user profile after signing, such as an external tool reading the key store, will no longer find it.
  • BreakingA response larger than 64 MB is now refused on every request the library makes, including timestamp, revocation, issuer certificate and EU trusted list downloads. Nothing published today comes close, the largest revocation list found anywhere is under 11 MB, but a deployment whose authority publishes something unusually large will need HTTPOptions.MaxResponseSize raised, or set to 0 for no limit at all.
  • BreakingA signature container entry that decompresses to more than 256 MB, or that expands by more than 200 to 1 above a floor of 1 MB, is now refused. The largest expansion measured across every sample in the tree is under 24 to 1, so no legitimate file is affected.
  • BreakingAuthenticode: a program with a section gap or an overlapping layout that was signed by an earlier version carries a hash Windows rejects, and has to be signed again. Programs built with the GNU linker and programs compressed with UPX are the two common cases. Verification of such files is now correct, so files that were wrongly reported as modified now verify.
  • BreakingCatalog files signed with extra certificates by an earlier version are not readable by Windows and have to be signed again. Signatures that carry no extra certificates are byte identical to before.
  • BreakingThe command line client now refuses --add-cert where it previously accepted it and quietly did nothing: with any format other than authenticode or catalog, and with authenticode in upload mode or with a provider chain. The signature was shipping without the certificates that were asked for, so this is now an error rather than a silent omission.
  • BreakingServer: a configuration file holding native Windows paths, such as a value written as C:\Users\name\cert.pem rather than with doubled separators, is repaired automatically on the first start after upgrading, and the original is kept beside it with a .pre-escape-migration.bak extension. Where a value is genuinely ambiguous the server refuses to start rather than guess, and names the file, the line and the fix. The realistic case is a path whose only escape is one of \b \f \n \r or \t, C:\temp being the obvious one.

sgcSign 2026.8.0

  • 2026.8.0: 2026 August
  • NewNew TsgcXMLDSigSigner component: signs XML with plain XML-DSig, no XAdES properties. One generic component driven entirely by configuration, so a signed SAML 2.0 assertion and a SOAP WS-Security message are two configurations of it rather than two different components.
  • NewSign any element by its ID attribute. The attribute name is configurable because it differs by standard: ID for SAML, wsu:Id for WS-Security, Id for XAdES. The signer can add it when the element does not have one.
  • NewSupport for the InclusiveNamespaces PrefixList of exclusive canonicalization, needed when a prefix appears only inside an attribute value such as xsi:type="xs:string". Without it the declaration is dropped and the digest changes, which is a common cause of a counterparty rejecting a signature.
  • NewSignature placement control: first or last child of any element, or immediately before or after a named sibling. SAML requires the signature between saml2:Issuer and saml2:Subject.
  • NewKeyInfo content is selectable: certificate, subject name, issuer and serial, RSA key value, or any combination.
  • NewTsgcDocumentSigner can produce plain XML-DSig, by setting Format to sfXMLDSig and configuring its XMLDSig property.
  • NewsgcSign Server: new /api/v1/sign/xmldsig endpoint with the same configuration as JSON, documented in the OpenAPI specification.
  • NewRSASSA-PSS signatures are now verified, covering the MGF1 forms and explicit PSS parameters. A variant that cannot be checked is reported as indeterminate with the reason. The German EU Trusted List now verifies.
  • NewDocuments carrying more than one signature are now fully verified, every signature checked.
  • Newsgcsign CLI: new WinHTTP transport, the default on Windows, which signs over HTTPS without any OpenSSL DLL. TLS 1.2 and 1.3 come from the operating system, trust comes from the Windows certificate store, and the system proxy settings are honoured. The new --transport option selects auto, winhttp or indy.
  • Newsgcsign CLI: new --openssl-api, --openssl-dir, --cacert and --tls-version options for the indy transport. --openssl-api defaults to auto, which probes OpenSSL 3.0, then 1.1, then 1.0, and uses the newest library that loads, so the client is no longer tied to OpenSSL 1.0.2. Each option also reads an environment variable: SGCSIGN_TRANSPORT, SGCSIGN_OPENSSL_API, SGCSIGN_OPENSSL_DIR, SGCSIGN_CACERT and SGCSIGN_TLS_VERSION.
  • NewsgcSign Server: new server.tls.provider setting, openssl or schannel. With schannel the HTTPS listener uses the Windows TLS stack and needs no OpenSSL DLL at all, taking either a PFX through cert_file and password, or a certificate already in the Windows store through cert_hash, cert_store_name and cert_store_path.
  • NewsgcSign Server: new server.tls.openssl_api setting, auto by default, which probes OpenSSL 3.0, then 1.1, then 1.0 and uses the newest library that loads. An explicit 1.0, 1.1 or 3.0 pins one generation. New server.tls.openssl_dir and server.tls.version_min settings, and the startup banner now reports the TLS provider and the API actually in use.
  • NewsgcSign Server: the TLS certificate password can be supplied through server.tls.password_env, which names an environment variable and takes precedence over the literal password key, matching how every other secret in the configuration file is handled.
  • FixedSecurity: a document with two or more signatures was reported as valid after checking only the first one. The enveloped-signature transform also removed the first signature in the document rather than the one being verified, and reused the first SignedInfo when checking any later signature.
  • FixedSecurity: a processing instruction whose target starts with "xml", such as the common xml-stylesheet, was discarded as if it were the XML declaration and left out of the digest, so it could be deleted or altered after signing while the signature still verified. Documents of that shape should be signed again.
  • FixedEU Trusted Lists and any document using xml:lang or another xml: attribute failed verification. The xml prefix is bound by the XML specification and never declared with xmlns, but was treated as undeclared, so canonicalization emitted a spurious xmlns:xml="" and sorted the attribute into the wrong group. Output now matches an independent implementation.
  • FixedSignature verification could be misled by a decoy. The signature was located with a plain text search, so something resembling a signature inside a comment, CDATA section, processing instruction or DOCTYPE internal subset could capture it, or capture a reference by its Id.
  • FixedCanonicalization emitted a line break for a comment before the root element even under a method that strips comments and produces no output for it, so signatures over such documents did not match what a conforming verifier computed.
  • FixedDocuments starting with a UTF-8 byte order mark failed to parse, so verification failed on signatures that were perfectly sound.
  • FixedSigning failed on a document with a comment, processing instruction or DOCTYPE before the root element, and a DOCTYPE with an internal subset failed to parse. With a signature parent element configured, a prolog comment containing text resembling a closing tag could place the signature inside that comment.
  • FixedSignatures referencing an element by its ID, and the SignedInfo element, are now canonicalized with the namespaces inherited from their ancestors, as the specification requires. Signatures made by earlier versions under an inclusive canonicalization profile are still accepted and reported as such, so they stay usable while telling you to sign again; the new TsgcSignatureVerifier.StrictCanonicalization property turns that acceptance off. The reference covering your document is always verified strictly.
  • FixedEU Trusted Lists were being damaged by our own downloader, which moved these signed documents as text and re-encoded them on the way to the cache, changing bytes and breaking the signature. They are now carried as bytes end to end, and a document that is not valid UTF-8 is reported as an error instead of being guessed. A list cached by an earlier version may already be damaged, so refresh the cache once after updating.
  • FixedDemos: a certificate provider could be released while an interface pointing at it was still alive, which could crash the demo. The Authenticode, ClickOnce, NuGet and VSIX demos leaked a provider on every signing operation, and EU_Employment reported its own containers as invalid by passing the whole signature file, envelope included, to the verifier.
  • FixedPFX certificates: fixed an error when signing on 64-bit Windows with a certificate that uses a modern CNG private key. Signing could fail with "NCryptSignHash failed: NTSTATUS=$200000000" even though the certificate and the password were correct. The signature was in fact created correctly, the problem was the check on the result, so nothing signed before the error appeared was affected. 32-bit applications were never affected.
  • Fixedsgcsign CLI: signing over HTTPS could fail with "server unreachable: server closed the connection without sending a response (server-side error)" when the fault was entirely on the client. Every OpenSSL failure, including being unable to load the library at all, was reported as a server error, which sent users looking at a server that was working correctly. Client side TLS failures are now reported as TLS errors, naming the libraries that were tried and the bitness of the process, and exit with the new code 7.
  • Fixedsgcsign CLI: the client could only load the OpenSSL 1.0 API, so it required libeay32.dll and ssleay32.dll and could not use OpenSSL 1.1 or 3.x. The server had the same restriction. Both now select the API generation, and both default to detecting the newest one available.
  • Fixedsgcsign CLI: the TLS connection offered SSL 2.0 and SSL 3.0 alongside the TLS versions. Only TLS 1.0 through 1.3 are offered now, and --tls-version raises the minimum.
  • FixedDocumentation: the technical guide stated that the server accepted the OpenSSL 1.1 and 3.x library names. That was never true, the server always loaded the OpenSSL 1.0 API. The guide now documents the TLS provider settings, the CLI TLS options and the full list of CLI exit codes.
  • FixedPAdES: signing never finished. It hung at 100% CPU on any PDF, because two loops that copy bytes out of the document never advanced their index and so kept reading the same byte. The first reads the document Catalog dictionary and runs on every signature, which is why no PDF could be signed. The second reads an object number and runs when the Catalog cannot be read from a classic trailer, as in PDFs that use a cross-reference stream, and on every visible signature to locate the page object; that one also grew a string on each pass, so it ended in an out of memory rather than only spinning. The .NET implementation was never affected, it uses counted loops in both places. Reported by a customer with a sample PDF, thank you.

sgcSign 2026.7.0

  • 2026.7.0: 2026 July
  • NewKSeF bulk client: a "save now, decrypt later" workflow. You can save a pack's encryption key and IV to a small JSON file, save the downloaded encrypted parts as one .zip.aes file, and later decrypt and unzip that saved file using the JSON key, all without a live order or bearer token.
  • NewKSeF bulk demo: new "Save Pack + Keys" button (writes the .zip.aes plus a .keys.json) and a "Decrypt Saved Pack..." button that picks the .aes, finds its matching .json automatically, then decrypts and extracts it.
  • NewCertificate decoder (X.509): now exposes the full set of fields you would see in an online certificate decoder, including key size, friendly public-key and signature algorithm names, the serial number in colon and decimal forms, certificate policies, subject and authority key identifiers, the issuer name sub-fields, MD5/SHA-1/SHA-256 thumbprints, and the SubjectPublicKeyInfo (SPKI) SHA-256 pin. A new helper turns common OIDs into readable names.
  • NewNew CertificateInfo demo: loads a certificate from PEM, Base64, DER or a file and shows every field grouped like a certificate decoder, then runs an OCSP revocation check that finds the responder URL from the certificate itself.
  • NewCertificate issuer checking with real cryptographic verification: new methods confirm a certificate was actually signed by a candidate issuer (RSA and ECDSA) and match the issuer name and key identifiers. The CA-issuer and OCSP URLs are now available separately, and the CertificateInfo demo can verify the issuer and auto-load the issuing CA before the OCSP check.
  • NewCertificate names in LDAP form: new properties show the Subject and Issuer names in RFC 2253 / RFC 4514 (LDAP) style (CN first, comma-separated), alongside the existing X.500 order, so it is easy to compare a certificate name against tools and XML that use the LDAP string form.
  • NewPKCS#12 (.p12 / .pfx) support: the certificate class can now load a certificate straight from a password-protected .p12 or .pfx file, and save a certificate to a password-protected .p12. If the file contains several certificates, the main certificate is loaded and the remaining CA certificates are available separately. The PFX and PEM key providers can now also save the certificate together with its private key to a password-protected .p12, which means a PEM certificate and key can be converted into a .pfx.
  • NewXAdES B-LT and B-LTA signature levels: the signer can now embed the full validation material (all certificates plus the timestamp authority's chain) and revocation data (CRLs and OCSP responses), and B-LTA adds an archive timestamp for long-term validity. New properties for the OCSP client, extra certificates and CRL files on both signers; the EU qualified profile now produces genuine XAdES-B-LTA, and outputs validate as BASELINE-T/-LT/-LTA on the EU DSS validator. The XAdES demo gained B-LT and B-LTA variants.
  • NewTicketBAI per-province profiles for Araba, Bizkaia and Gipuzkoa, each with its tax authority's official signature policy (Gipuzkoa policy v1.2). The original combined profile keeps the Bizkaia values for backward compatibility. Bizkaia signatures were validated end to end against the official Batuz/LROE test environment (accepted as "Correcto", with a tampered signature correctly rejected). The TicketBAI demo gained a province selector.
  • NewPortugal SAF-T (Portaria 363/2010) invoice signing: a new signer produces the required RSA-SHA1 signature over the invoice fields, exposes the four printable characters carried on the invoice and in the QR code, and was verified against the official worked example. The SAF-T PT demo gained a signing panel.
  • FixedZIP extraction now does a proper raw inflate on XE2 and later, instead of wrapping the data in a fake zlib stream with a placeholder checksum that newer zlib rejected with "data error". This affects every ZIP extraction path (ASiC, KSeF bulk export); the older D7..DXE path is unchanged.
  • FixedKSeF bulk client: HTTP errors now include the server's response text (shown as "HTTP - <body>", trimmed), so a 400 or 403 shows the KSeF explanation instead of just the status code.
  • FixedKSeF bulk client: the bearer token is no longer attached when downloading pre-signed part URLs. KSeF serves the parts from Azure storage authenticated by the query-string signature, so sending the Authorization header made Azure reject the download with 403. The token is now dropped whenever the part URL has a query string.
  • FixedKSeF bulk client: responses are now read as UTF-8, so Polish characters in status messages display correctly instead of garbled text.
  • FixedKSeF bulk demo: a not-yet-downloaded part now shows "Ready" once the export is complete, instead of the confusing "Pending".
  • FixedKSeF bulk demo: on an HTTP error the log now shows the status line, all response headers and the body, so even body-less gateway rejections (401/403) show a reason and validation errors (400) show their message.
  • FixedKSeF bulk demo: when an export finishes with no parts, the log now explains that no invoices matched the chosen date range, subject type or date type, instead of a later bare "No parts to download".
  • FixedKSeF bulk demo: the date range now defaults to the current month on startup, which stays within the KSeF 3-month export limit, instead of a fixed past month.
  • FixedVeriFactu profile: corrected the signature policy. It referenced the Facturae policy with a SHA-1-length digest labelled as SHA-256, which strict validators reject; it now uses the Spanish AGE policy with its official SHA-1 digest and inclusive canonicalization, per Orden HAC/1177/2024.
  • FixedTicketBAI profile: fixed a malformed policy URL and a corrupted policy digest; it now carries the official Bizkaia v1.0 policy identifier and SHA-256 digest.
  • FixedFatturaPA profile: removed the signature policy reference. Italy's SDI accepts plain CAdES-BES or XAdES-BES signatures with no policy, so the profile now emits pure XAdES-BES.
  • FixedFiskalizacija profile: updated to Fiskalizacija 2.0 (the eRacun channel, in force since January 2026): RSA-SHA256 with exclusive canonicalization. The old cash-register channel used RSA-SHA1 with the ZKI code and is a separate mechanism.
  • FixedSignature profiles now have a single source of truth: one configuration holds every profile's values and both the signer and the server admin dashboard read from it, so they can no longer drift apart.
  • FixedEnveloping XAdES signatures are now verifiable by outside validators. The embedded object's digest is now computed over the canonicalized element with an explicit transform declared (instead of over raw bytes), and the reference now carries the matching Id, so it no longer dangles.
  • FixedThe XAdES signature-timestamp imprint is now spec-correct at every level: the hash is taken over the canonicalized signature-value element (with the canonicalization method declared) instead of the raw Base64 text, so timestamps pass strict verification such as the EU DSS.
  • BreakingSigning at the B-LT or B-LTA level now raises a clear error when no timestamp authority is set, or no revocation source (OCSP client or CRL files) is available, instead of quietly producing a lower level. This affects the EU qualified profile and the B-LT employment profiles (DE/IT/AT/BE/PT); the EU_Employment demo and console generator ship wired with a TSA and the new test CA material.

sgcSign 2026.6.0

  • 2026.6.0: 2026 June
  • NewNew sgcSign Server: self-hosted REST signing server (TsgcSignServer) that signs executables and documents remotely over a TLS HTTP API. Signs Authenticode PE files (exe/dll/sys/msi/cab/ocx, optional dual SHA-1 + SHA-256), PDF (PAdES), XML (XAdES, with country e-invoicing profiles), CAdES (detached PKCS#7), ClickOnce manifests, NuGet packages, VSIX extensions and PowerShell scripts, all with optional RFC 3161 timestamping, plus a signature verify endpoint.
  • NewsgcSign Server: pluggable key providers selected per request: Windows Certificate Store, PFX, PEM, PKCS#11 / HSM (YubiKey), AWS KMS, Azure Trusted Signing, Google Cloud KMS, HashiCorp Vault and Certum SimplySign; passwords, PINs and cloud secrets are read from environment variables instead of the config file.
  • NewsgcSign Server: browser admin console (dashboard, API keys, providers, users, projects, audit), API-key authentication with per-key rate limits and daily quotas, multi-tenant projects, optional sign-approval workflow, tamper-evident hash-chained audit log, Prometheus metrics, outbound webhooks and an OpenAPI 3.1 document with built-in Swagger UI.
  • NewsgcSign Server: runs as a Windows service or console application, configured by a single JSON file (sgcSignServer.conf.json) with a built-in firewall (IP allow/deny, brute-force and rate limiting), TLS with optional ACME / Let's Encrypt challenge serving, and SQLite storage. New command-line client "sgcsign" (sign, verify, keys, health) talks to the server with --server / --apikey and supports Authenticode pre-hash (--prehash), so CI agents upload a hash instead of the whole binary.
  • NewTsgcKSeFBulkClient: bulk-invoice-export pipeline (sgcSign_KSeF_Bulk), 4-step async-init
  • NewNew demo KSeFBulk: standalone VCL, all design-time controls
  • NewTsgcPAdESSigner.VisibleSignature: on-page visible signature appearance (Form XObject renders signer name, reason, location and signing date), wires the widget /AP /N and the page /Annots; active when VisibleSignature.Enabled is True
  • FixedTsgcKSeFCrypto.RSAOAEPEncryptWithCert: non-RSA cert early rejection w/ clear OID error
  • FixedTsgcPAdESSigner: signed PDFs are now linked into the document AcroForm (Catalog /Fields + /SigFlags 3) so Adobe Acrobat and other viewers detect the signature. Previous versions wrote a cryptographically valid signature that no viewer displayed, because the incremental update never re-emitted the /Root catalog with an /AcroForm. The signer now parses the real /Root, merges or creates the AcroForm, wires the signature field, and builds a multi-subsection xref.

sgcSign 2026.5.0

  • 2026.5.0: 2026 May
  • NewTsgcAuthenticodeSigner: Microsoft Authenticode signer for Windows PE files (.exe, .dll, .sys) with SHA-1/256/384/512, RFC3161 timestamps and nested signatures.
  • NewTsgcAuthenticodeVerifier: Authenticode signature verification for Windows PE files.
  • NewTsgcCMSBuilder: shared CMS/PKCS#7 builder used by CAdES, PAdES and Authenticode signers.
  • NeweIDAS / EU compliance pack: new sgcSign_ASiC (ASiC-S/E containers per ETSI EN 319 162-1), sgcSign_TrustList (LOTL/EUTL fetch + cache + IsQualifiedAtTime, ~3600 services across 31 MS), sgcSign_KeyProvider_CSC (Cloud Signature Consortium v2 client for remote QTSPs); 9 country employment profiles spEmploymentDE/IT/ES/FR/PL/AT/BE/PT/NL pre-tuned per member-state labour law.
  • NewNew demo EU_Employment showing the new features.
  • NewsgcSign Server: self-hosted remote code-signing daemon (sgcSignServer.exe, console + Windows service) exposing the full signing engine over a REST API and a Bootstrap web admin console; FireDAC/SQLite storage, PBKDF2-SHA256 admin passwords and API-key auth, SHA-256 hash-chained audit log, thread-safe per-provider sign dispatcher and 9 supported provider kinds (WinCertStore, PFX, PEM, PKCS#11, AWS KMS, Azure Trusted Signing, Google Cloud KMS, HashiCorp Vault, Certum); requires Delphi 10 Seattle or newer.
  • Newsgcsign command-line client and esegece.sgcSign.Client .NET SDK (netstandard2.0 / net6.0 / net8.0 / net9.0), plus esegece.sgcsign .NET global tool, with sign / verify / keys / health verbs and a shared exit-code contract.
  • NewHash-only Authenticode signing: new POST /api/v1/sign/authenticode/hash endpoint accepts a precomputed PE hash and returns the unattached PKCS#7 SignedData blob for local embedding by the client; sgcsign sign --prehash (Delphi CLI) and TsgcSignClient.SignAuthenticodeHashAsync (.NET SDK) round-trip a 32-byte hash instead of the full binary, dropping multi-megabyte uploads to a few KB on bandwidth-constrained CI agents.
  • NewTsgcClickOnceSigner: ClickOnce / VSTO manifest signer (.application / .exe.manifest) using enveloped W3C XML-DSig per Microsoft mage.exe spec.
  • NewTsgcNuGetSigner: NuGet author package signer (.nupkg) producing PKCS#7 SignedData with optional RFC3161 timestamp.
  • NewTsgcVSIXSigner: VSIX (Open Packaging Convention) digital signature signer with per-part XML-DSig references.
  • NewCI/CD integrations: GitHub Actions composite Action, Azure DevOps native task, Jenkins pipeline DSL, Windows Server Core Dockerfile + docker-compose, Helm chart.
  • NewsgcSign_QRCode unit: pure-Pascal QR Code generator per ISO/IEC 18004, byte mode, all four ECC levels, versions 1-40, GF(256) Reed-Solomon, full mask-penalty scoring, TBitmap renderer; published GenerateQRCode + RenderQRMatrix + GetAlignmentPositions.
  • NewKSeF demo: Online vs Offline mode tabs.
  • NewTsgcPEMKeyProvider: ECDSA P-256/P-384/P-521 support via BCrypt CNG (BCryptImportKeyPair with ECCPRIVATEBLOB, raw r||s SignData output for XML-DSig); new SignDataPSS method (BCryptSignHash + BCRYPT_PAD_PSS, SHA-256, salt=32) for RSA-PSS signatures.
  • NewTsgcSignatureVerifier: ECDSA signature verification (ImportECDSAPublicKey from BCRYPT_ECCPUBLIC_BLOB + VerifyECDSASignature) for curves P-256/P-384/P-521 in both VerifySignatureValue (XAdES) and VerifyData code paths.
  • NewTsgcX509Certificate: KeyUsage extension parsed and exposed via KeyUsage property + HasKeyUsageDigitalSignature / HasKeyUsageNonRepudiation helpers; new PublicKeyParameters property exposes the raw AlgorithmIdentifier parameters TLV (named-curve OID for EC certs, used by the verifier to import EC public keys).
  • NewTsgcProfilePeppolBG: new Bulgarian Peppol BIS Billing 3.0 signature profile (XAdES B-T, SHA-256, exclusive C14N, timestamp on); spPeppolBG enum value, server admin profiles grid entry "Peppol BG / Bulgaria", Server REST string mapping peppolbg / peppol_bg, Delphi and C++Builder demos signing a Bulgarian UBL 2.1 Invoice (BGN, 20% VAT, BG VAT/EIK, BG IBAN, schemeID 9926 endpoint).
  • FixedTsgcPEMKeyProvider hardened end-to-end: Unicode ReadFileContent fix, two-step PKCS#8 decode, AT_KEYEXCHANGE keyspec, GUID-suffixed CSP container, native encrypted PKCS#8 (PBES2/PBKDF2/AES-CBC) via BCrypt, LoadCertificateOnly + EC marker recognition.
  • FixedTsgcXAdESSigner KSeF/ETSI conformance: V1 SigningCertificate wrapper, conditional SignaturePolicyIdentifier emission, decimal X509SerialNumber, SignedProperties built once (clock-race fix), explicit exc-c14n Transforms on SignedProperties Reference, new SignatureParentElement property; TsgcSignatureVerifier now resolves URI=#<Id> by element-Id lookup.
  • FixedTsgcPFXKeyProvider supports modern P12s: PKCS12_PREFER_CNG_KSP + multi-cert iterate-and-probe + two-stage acquire (ONLY_NCRYPT then PREFER_NCRYPT), CNG signing via NCryptSignHash. Design-time component linkage gains Notification(opRemove) auto-clear across all 9 signer/verifier components. KSeF demo migrated to FA(3) and PEM provider.
  • FixedTsgcX509Certificate ParseExtensions: the X.509v3 [3] EXPLICIT Extensions tag content was being double-wrapped before parsing, causing KeyUsage, ExtendedKeyUsage, AIA, CDP, SubjectAltName and BasicConstraints to be silently skipped on every certificate.
  • FixedBuild hygiene: W1000 (UTF8Decode deprecated) in sgcSign_ASiC fixed via {$IFDEF UNICODE} UTF8ToString fallback; H2077 (vTailLen unused) in sgcSign_XAdES; H2219 dead-code symbols BuildQualifyingProperties (sgcSign_XAdES) and ExtractAttribute (sgcSign_TrustList) removed.
  • FixedTsgcSignatureVerifier: ExtractFullElement now handles XML self-closing tags (<ds:DigestMethod Algorithm=".../sha1"/> etc.). Previous versions returned an empty string, causing URIToHashAlgorithm to default to SHA-256; FacturaeB2B (SHA-1) verification then reported "Digest length mismatch for Reference 0".
  • FixedTsgcSignatureVerifier: applies implicit Inclusive C14N to fragment / empty-URI references that omit an explicit C14N transform, per XML-DSig section 4.3.3.2. Fixes "Digest value mismatch" on the KeyInfo and body references in inclusive-C14N profiles (FacturaeB2B).
  • NewTsgcDocumentSigner: high-level facade now properly produces XAdES for AdES profiles. Internally delegates to TsgcXAdESSigner for the sfXAdES path; raises a clear error for sfPAdES/sfCAdES (use TsgcPAdESSigner / TsgcCAdESSigner). Added published Format: TsgcSignatureFormat property (default sfXAdES). Previous versions emitted plain XML-DSig regardless of profile, which national e-invoicing services rejected.
  • NewTsgcPFXKeyProvider: new published HashAlgorithm property (default haSHA256). TsgcXAdESSigner now pushes the active profile's hash into PFX providers, so FacturaeB2B-signed PFX-backed invoices are RSA-SHA1 as the profile requires; previous versions hardcoded SHA-256 in the PFX path and FACe rejected with INVALID_INVOICE-122 "los datos de la firma no son correctos".
  • NewWideString overloads on the public signing/verification API: TsgcXAdESSigner.SignXML/SignXMLDetached/SignXMLEnveloping, TsgcDocumentSigner.SignXML/SignXMLDetached/SignXMLEnveloping, TsgcSignatureVerifier.Verify. Lossless Unicode in/out on Delphi 7 (no ACP step); equivalent to the string overloads on Delphi 2009+. Recommended for callers passing non-ACP text such as Polish characters.

sgcSign 2026.4.0

  • 2026.4.0: 2026 April
  • NewTsgcDocumentSigner: high-level document signing component supporting XAdES, CAdES and PAdES formats.
  • NewTsgcXAdESSigner: XAdES XML Advanced Electronic Signature implementation.
  • NewTsgcCAdESSigner: CAdES CMS Advanced Electronic Signature implementation.
  • NewTsgcPAdESSigner: PAdES PDF Advanced Electronic Signature implementation.
  • NewTsgcSignatureVerifier: signature verification component.
  • NewTsgcXMLDSigEngine: XML Digital Signature engine.
  • NewTsgcC14NEngine: XML Canonicalization engine.
  • NewTsgcHashProvider: hash computation component.
  • NewTsgcTSAClient: Timestamp Authority client.
  • NewTsgcOCSPClient: OCSP certificate status verification client.
  • NewTsgcCRLCache: Certificate Revocation List cache.
  • NewTsgcX509Certificate: X.509 certificate handling.
  • NewTsgcASN1Parser: ASN.1 structure parser.
  • NewTsgcWindowsCertStoreProvider: Windows Certificate Store key provider.
  • NewTsgcPFXKeyProvider: PFX/PKCS#12 file key provider.
  • NewTsgcPEMKeyProvider: PEM file key provider.
  • NewTsgcPKCS11Provider: PKCS#11 hardware token key provider.
  • NewTsgcAWSKMSKeyProvider: AWS Key Management Service key provider.
  • NewTsgcAzureTrustedSigningProvider: Azure Trusted Signing key provider.
  • NewTsgcGCloudKMSKeyProvider: Google Cloud KMS key provider.
  • NewTsgcCertumSimplySignProvider: Certum SimplySign key provider.
  • NewTsgcHashiCorpVaultKeyProvider: HashiCorp Vault key provider.
  • NewTsgcProfileVeriFactu: Spanish VeriFactu e-invoicing profile.
  • NewTsgcProfileTicketBAI: Basque Country TicketBAI e-invoicing profile.
  • NewTsgcProfileFacturaeB2B: Spanish FacturaE B2B profile.
  • NewTsgcProfileEIDAS: eIDAS qualified electronic signature profile.
  • NewTsgcProfileFatturaPA: Italian FatturaPA e-invoicing profile.
  • NewTsgcProfileSAFTPT: Portuguese SAF-T e-invoicing profile.
  • NewTsgcProfileKSeF: Polish KSeF e-invoicing profile.
  • NewTsgcProfileFacturX: French Factur-X e-invoicing profile.
  • NewTsgcProfileEFactura: Romanian eFactura e-invoicing profile.
  • NewTsgcProfileNAVOnline: Hungarian NAV Online e-invoicing profile.
  • NewTsgcProfileFiskalizacija: Croatian Fiskalizacija e-invoicing profile.
  • NewTsgcProfilePeppolBE: Belgian Peppol e-invoicing profile.
  • NewTsgcProfileMyDATA: Greek myDATA e-invoicing profile.

Get the current release

Every licence includes a year of updates, and the trial is the full product.