sgcSign 2026.10.0 Latest
- 2026.10.0: 2026 October
- NewCzech EET 2.0 support (Elektronicka evidence trzeb, the electronic registration of sales). A new TsgcEETClient component sends a registered sale to the Czech tax authority and reads the answer back: it signs the message with the taxpayer's certificate, checks the signature on the acknowledgement that comes back, and reports the acknowledgement code (pok) together with any warnings the tax authority raised. Verification mode lets a taxpayer confirm the connection works without reporting a sale, the message is checked in full and nothing is filed. The message can also be built and signed without being sent, so an offline queue can store it while the line is down and send it later, and a sale that was never acknowledged can be replayed as a repeat submission. Reporting starts on 1 January 2027 and the tax administration playground is open now, which is where the component points by default, so a first test can never file a real sale.
- NewWindows Installer packages can now be signed. A new TsgcMSISigner component signs .msi and .msp files with SHA-1, SHA-256, SHA-384 or SHA-512, adds an RFC 3161 timestamp, and can add a second signature to a package that is already signed, exactly the way the Authenticode signer does for an exe or a dll. Requested by a customer, thank you.
- NewMSIX and APPX packages can now be signed. A new TsgcAppxSigner component signs .msix, .appx and their bundles and writes the signature into the package as AppxSignature.p7x. Windows only accepts SHA-256 for a package, so that is the only digest offered, and signing a package that is already signed replaces the old signature. If the package does not yet declare the signature part, it is added for you. Requested by a customer, thank you.
- NewThe Authenticode verifier now recognises what it was given and checks a Windows Installer package and an MSIX or APPX package as well as an exe or a dll. The call and the result are the same as before, so nothing changes for code that already verifies PE files.
- NewSignature server: two new formats, msi and appx, reachable at /api/v1/sign/msi and /api/v1/sign/appx. Both take the whole file, the same way the catalog format does. The command line tool accepts them as --format msi and --format appx.
- NewSignature server: an API key can now have a total call quota beside its per minute limit, daily quota and expiry. Only a call that passed every check is counted, so a call refused with 429 never uses up the quota, and concurrent calls can never go past it. A key that has used its quota is answered with 403 and the error quota_exhausted, without Retry-After, and it stays active. The admin console sets the quota when a key is created and edits it in the key list, shows the calls made against it, and a new Reset count action sets the count back to 0, so raising the quota or resetting the count lets the key work again at once.
- NewWS-Security signatures, for any SOAP 1.1 service that asks for a signed message. The signature can now carry its certificate the way the standard expects, as a binary security token held in the message with the signature pointing at it, instead of repeating the certificate inside the signature itself. The verifier follows that pointer and picks the certificate out of the message, so a signature that arrives in that shape can now be checked as well as produced. A SOAP 1.1 envelope builder is included, so the body, the token and the signature end up where the standard puts them.
- NewThe shared HTTP transport now hands back the response headers as well as the status code and the body, and a new helper reads a single header by name, matching the name case insensitively. It matters the moment a service puts something you need in a header and nowhere else: the Czech EET service returns a tracing identifier that its support desk asks for first, and until now there was no way to read one.
- NewSignature server: a new EET route at /api/v1/sign/eet builds and signs a Czech registered sale with a key the server holds, and optionally posts it to the tax authority and returns what came back. A chain of point of sale terminals can therefore share one taxpayer certificate kept on the server, instead of every till holding a copy of it.
- NewThe command line tool gained the matching eet verb, which reads the sale from a JSON file, has the server sign it, and with --submit sends it. The exit code says what happened, because a till script has to tell a refusal from a broken line: 6 means the tax authority rejected the sale, so it is not reported and has to be stored and sent again, 5 means the server could not sign it or could not reach the tax authority at all, and 4 means the sgcSign server itself could not be reached.
- NewThe command line tool now has an exit code of its own for a request the server read and refused, 8, and for a request it rate limited, 9. Until now both ended up on the generic 1, which left a till script unable to tell a sale the tax authority called invalid, which must never be sent again, from one that failed because the line was busy, which must be. Code 8 covers HTTP 400, 404, 409, 413 and 415 and is never worth retrying, code 9 covers HTTP 429 and is worth retrying after a delay, which the tool now prints when the server says how long to wait. Read this as a change to the contract: a script that compares the exit code to exactly 1 stops matching an invalid request, and has to test for 8 and 9 as well. Codes 0 and 2 through 7 are untouched, and the health verb still reports anything other than a refused credential as unreachable.
- NewEvery key provider now has a read only IsLoaded property, which is True once the call that loads its certificate and key has been made, so a program can check first instead of waiting for an exception. The Windows certificate store provider already had it, and its value there is unchanged.
- NewSignature server: an installer or a package can now be signed without uploading it. Two new routes, /api/v1/sign/msi/hash and /api/v1/sign/appx/hash, take only the digest of the file and hand back the signature, so a large installer never crosses the network and the server never spends time reading it. On your side the package is prepared, hashed, and the signature that comes back is written into it, with sgcMSIPrepareForSigning, sgcMSIComputeHash and sgcMSIEmbedSignature for an installer, and sgcAppxPrepareForSigning, sgcAppxComputeDigestBlob and sgcAppxEmbedSignature for a package. Prepare first and hash what prepare gave you, because that is what the signature covers. The command line tool now works this way by default for --format msi and --format appx, the same as it already did for --format authenticode, and --upload sends the whole file instead. Requested by a customer, thank you.
- NewSignature server: the hash routes now also return signer_subject, the subject of the certificate that signed. It lets a caller see which identity signed without holding the certificate, which matters for an MSIX or APPX package, where the publisher written in the package has to be exactly that subject and nothing else in this flow can check it.
- NewThe QR code generator no longer needs the VCL, so it can be used on Linux, macOS, iOS and Android and in FireMonkey applications. RenderQRMatrix, which draws on a VCL TBitmap, is still there for Windows VCL projects and is left out of FireMonkey projects (Delphi 11 and later) and of any build that defines SGC_SIGN_NO_VCL.
- NewsgcSign now builds and runs on Linux, macOS, iOS and Android as well as Windows. Signing a document, producing and checking a signature, reading and writing a PKCS#12 file, hashing and signing a PE file or a Windows Installer package, and talking to a timestamp authority, an OCSP responder or a cloud signing service are the same code on every platform, and the file that comes out is the same file. The runtime packages are built for Linux64 and macOS on Intel from Delphi 10.3, for Android and iOS from Delphi 10.4, and for macOS on Apple Silicon and the ARM iOS simulator from Delphi 11; the installer offers those platforms and adds the library path for each one. Delphi 10.2 has no Linux64 build because its Linux compiler has no AnsiString, which the library uses. Nothing changes on Windows: the same components, the same properties, the same bytes out, and Delphi 7 onwards builds exactly as it did.
- NewCode signing no longer needs Windows. TsgcAuthenticodeSigner, TsgcCatalogSigner, TsgcMSISigner, TsgcAppxSigner and TsgcAuthenticodeVerifier build and run on Linux, macOS, iOS and Android as well, so an exe, a dll, a .cat catalog, an .msi, an .msp, an .msix and an .appx can be signed and checked on a build agent that is not a Windows machine. The file produced is the same file: everything these components do is the signature format itself, so the same key over the same input writes the same bytes on every platform, and Windows accepts a package signed on Linux exactly as it accepts one signed on Windows. Nothing changes for a Windows program, the API, the properties and the output are untouched. The key still has to come from somewhere the platform can reach, so the Windows certificate store provider stays Windows only while the PFX, PEM, PKCS#11 and cloud providers work everywhere. The signature server and the command line tool sign and verify these formats on every platform too.
- NewTwo new key providers, for the keystore the platform already has. TsgcAppleKeychainProvider finds an identity in the macOS or iOS keychain by SHA-1 thumbprint, subject or label, lists what is there the way the Windows store and PKCS#11 providers do, resolves the issuing certificate from the keychain, imports a PKCS#12, and signs through the keychain so the private key never leaves it, with RSA and with ECDSA on P-256, P-384 and P-521. TsgcAndroidKeyStoreProvider does the same against AndroidKeyStore, selecting by alias, thumbprint or subject, taking the certificate chain from the store, and it can open the system credential chooser to let the user pick a key or the platform import screen to install a PKCS#12. Both are driven by the signers like any other provider, and both are inert on a platform that is not theirs. Be aware that the keychain and KeyStore calls themselves have not yet been run on a real Mac, iPhone or Android device, because there is none here to run them on; everything around them is covered by the test suite. Tell us what does not work and it will be fixed.
- NewPKCS#12 files are read and written without Windows. A .pfx or .p12 is now parsed and produced by sgcSign itself: the MAC is verified before anything is decrypted, PBES2 with PBKDF2 and AES-128, AES-192, AES-256 or 3DES is supported together with the older pkcs-12 schemes, and RC4 and public key protected files are refused by name instead of failing obscurely. Files written by OpenSSL 1.1, OpenSSL 3 and Windows all load, and a file sgcSign writes opens in all three. TsgcPFXKeyProvider therefore loads a file, reports the key algorithm, signs data and digests with RSA and EC keys, resolves issuers inside the file and saves back to PFX on every platform. On Windows the certificate store and its key handles are still used, so nothing there changes.
- NewThe crypto the library needs is now inside the library. On Windows it still runs through CNG and CryptoAPI exactly as before; everywhere else it runs on sgcSign's own pure Pascal implementation of SHA-1 and SHA-2, HMAC, PBKDF2, AES, 3DES, RC2, RSA with PKCS#1 v1.5, PSS and OAEP, and ECDSA on P-256, P-384 and P-521. Nothing is linked, nothing is downloaded and there is no OpenSSL to deploy with your application. The private key operations are written to take the same time whatever the secret is and to check their own result before returning it, so a signature is never emitted from a faulty computation.
- NewHTTP requests work on every platform. On Windows the transport is still WinHTTP and behaves as it always did; elsewhere it is the RTL HTTP client, and the timestamp, OCSP, CRL, KSeF, EET and cloud provider calls all go through it with no change to your code. A client certificate can now be given as a PFX or PEM file with a password, which is how a platform with no Windows certificate store presents one, and an option the platform cannot honour is refused with a message that names it.
- NewThe signing server runs on Linux. The Linux build is a foreground daemon that handles SIGTERM and SIGINT, flushes every line so journald sees it, and is installed as a systemd unit with the script that ships with it. It finds its data directory from XDG_DATA_HOME, then HOME/.local/share, then /var/lib/sgcsign, then the folder the executable is in, and it uses file locking for the single instance check. The Windows service is untouched. Authenticode, PowerShell, catalog, MSI and MSIX or APPX are signed and verified on a Linux server exactly as they are on Windows. A provider configured to use the Windows certificate store is refused when the server starts, with a message saying why.
- NewThe Linux signing server now ships prebuilt. The release carries the Linux64 daemon and its systemd unit beside the Windows binaries, installed as apps\Linux64\sgcSignServer and apps\Linux64\sgcsignserver.service, so a Linux deployment no longer has to be compiled first.
- NewEvery component now declares the platforms it runs on, so from Delphi 10.3 the Tool Palette offers a component only where sgcSign has a compiled unit for it. TsgcWindowsCertStoreProvider is offered on Windows only and TsgcPKCS11Provider everywhere except iOS, which has nowhere to load a PKCS#11 module from. Everything else is offered on every platform the runtime package is built for.
- NewThe signing server and the command line tool sign and check PowerShell scripts. The server route /api/v1/sign/powershell signs a script and the verify route checks one, and both take the file name, which decides the comment style, and the code page for a file with no byte order mark. The answer says which style and which code page were used. The command line tool has the same through --format powershell and --codepage. Before this the route always failed, because it was handing the script to the signer for programs.
- NewSignature server: API keys can now be created in bulk. The create form in the admin console takes a number of keys, up to 10000 at a time, all with the same project, expiry, rate limit and quotas, and they are created all together or not at all. The new keys come back once, as a CSV file download. The server keeps only a hash of each key, so the file can never be downloaded again. The API keys page now shows 100 keys per page and can be filtered by name or id. Requested by a customer, thank you.
- NewSignature server: delegated administrators and child API keys. A new delegated_admin role can be put in charge of a top-level key and splits it into child keys for its own users, one at a time or in bulk. A child key always belongs to the project of its parent, cannot expire after it, and the total quotas of the children together can never exceed the total quota of the parent, which the calls made with the parent itself also draw on. A delegated administrator sees only its own keys and their children, cannot change the parent key, cannot reset a count and has no access to the rest of the console. Disabling the parent key stops every child key at once, and a key that still has children cannot be deleted. Requested by a customer, thank you.
- NewPowerShell scripts can now be signed and checked, on every platform. A new TsgcPowerShellSigner signs a .ps1, .psm1, .psd1, .ps1xml, .psc1, .cdxml or .mof file the way Windows does it, writing the signature as the comment block at the end of the file, and TsgcAuthenticodeVerifier checks one. Windows accepts what the component produces, including a script signed on Linux, and reports a script that was altered afterwards as changed. Signing again replaces the old block instead of adding a second one. A script that has no byte order mark is read in the code page you choose, 1252 by default off Windows, so a plain text script gives the same signature on every machine. A script whose own text contains a signature marker line is refused with a message saying so, because Windows refuses it too.
- NewSignature server: every admin console user can now change their own password, whatever their role. Until now only an admin could change a password, from the Users page. A new My account page, in the menu just above Logout, asks for the current password, the new password and its confirmation. The new password needs at least 8 characters and must differ from the current one, the change is written to the audit log, and every session of the account ends so the user signs in again with the new password. Available in every edition. Requested by a customer, thank you.
- NewPAdES visible signature placement. VisibleSignature.Page is now honored, and a negative value counts from the end, so -1 always means the last page, whatever the page count. The new Pages property puts the same signature on several pages at once, either 'all' or a list such as '1,3,5-7,-1', which is how documents that need the signer's initials on every page are signed. It stays one signature, shown on each listed page. Requested by a customer, thank you.
- NewPAdES visible signature anchoring. The new Anchor property places the stamp in a corner, at the center of an edge or in the middle of the page, with MarginX and MarginY as the distance from the edges (36 points by default). The position is worked out for each page, so the stamp lands in the same place on A4, A3 and landscape pages, and it stays upright on pages that are rotated. The default keeps the fixed Left, Bottom, Right and Top coordinates, as before.
- NewPAdES: a PDF template that already has an empty signature field can now be signed into it. Set SignatureFieldName to the name of that field and the signature uses the field's own page and rectangle. When a field with that name is already signed, the new signature takes the next free name (Signature1 becomes Signature2) instead of creating a second field with the same name.
- NewPAdES visible signature appearance. The new Text property is a template for the stamp, one line per entry, with {SIGNER}, {REASON}, {LOCATION}, {CONTACTINFO}, {DATE} and {ISSUER}, so the labels can be written in any language, accented characters included. A line whose values are all empty is left out. DateFormat sets how the date is written, and TimeZone can add the UTC offset (-03:00) or show the time in UTC. The date shown is exactly the signing time stored in the signature. Transparent draws the stamp with no background, so the page content under it stays visible, and WordWrap (on by default) wraps long lines inside the rectangle. Requested by a customer, thank you.
- NewPAdES visible signature image and QR code. The stamp can show a JPEG or PNG image, such as a company logo or a handwritten signature (PNG transparency is kept), on the left, right, top or as a background. It can also show a QR code, for example pointing to the service where the signature is validated, drawn as vector graphics so it scans cleanly at any size. Leaving these properties empty keeps the stamp exactly as before.
- NewSignature server: the API keys page now shows who created each key, with an Administrator or Delegated admin badge, and a Created by filter separates the keys created by administrators from those created by delegated administrators. Keys created before this version are shown as created by an administrator when they are top-level keys. Requested by a customer, thank you.
- NewSignature server: two-factor sign-in for the admin console. A user turns it on from My account by adding the account to any authenticator app (TOTP), and from then on the console asks for a code from the app after the password. Ten recovery codes, shown only once, sign in when the phone is not at hand, and a new set can be issued at any time. An administrator can reset the second factor of a user who lost the device with Reset 2FA on the Users page. Setting admin.require_2fa to true (false by default) makes it compulsory: an account without it reaches only My account and Logout until it enrolls. Turning it on, turning it off, an administrator reset and every wrong code are written to the audit log and can be sent as webhooks.
- NewSignature server: the admin console can now be signed in to with OpenID Connect, so users sign in with the identity provider the company already has, for example Microsoft Entra ID, Google, Okta or Keycloak, instead of a separate password. Any standard OpenID Connect provider works, several can be configured, and the sign in uses the authorization code flow with PKCE. A provider identity is linked to an existing console user, and with auto_link_by_email (false by default) it is linked by its verified email address at the first sign in. With allow_account_requests (false by default) a person who has no console account can ask for one, and an administrator approves or denies the request in the console. When the identity provider already asks for a second factor, skip_local_2fa (false by default) stops the console asking for its own code as well.
- NewSignature server: the secrets in the configuration file are now encrypted at rest. Provider passwords and PINs, cloud credentials, webhook secrets, the TLS certificate password, the SMTP password, the backup passphrase and the OpenID Connect client secrets are stored as enc:v1: values, encrypted with a master key the server creates at the first start and binds to the machine, with DPAPI on Windows and a file only the service account may read on Linux. A stolen copy of the configuration file therefore reveals none of them, and the two-factor secrets in the database are protected with the same key. Secrets saved from the admin console are stored encrypted, and the new --protect-secrets switch encrypts the plain values already in an existing file, keeping the original as a .bak copy (--dry-run only lists them). A value that cannot be decrypted is never used: the provider stays unavailable, the webhook does not deliver and a TLS password stops the start, each with a message naming the setting and the master key file.
- NewSignature server: the admin console is harder to attack. Every page is sent with security headers and a strict Content Security Policy, and a failed sign in shows the same message whether the username or the password was wrong, so it no longer tells anyone which accounts exist. The new admin.password_policy sets the rules for every console password (at least 8 and at most 128 characters by default, and optionally an upper case letter, a lower case letter, a digit and a symbol). A password set by an administrator, for a new user or on a reset, is temporary and has to be changed at the next sign in before anything else can be done. When the role or the projects of a user change, every session of that user ends, so the new rights apply at once.
- NewSignature server: more control over the life of an API key. Regenerate gives a key a new secret on the same row, so its id, limits, project and child keys stay, and the old secret can keep working for 1 hour, 24 hours or 7 days while the consumers switch (by default it stops at once). The expiry of an existing key can now be set, extended, shortened or cleared, and the key list shows who owns each key. With api_keys.self_service (false by default) operators get a My API keys page where they create and manage their own keys, within the caps of api_keys.self_service_limits (5 keys, 60 calls per minute and 1000 calls per day by default). A key can also be limited to some of the providers of its project: a request that names another provider is refused with 403 provider_not_allowed, and /api/v1/keys lists only the providers the key may use.
- NewSignature server: approvals are now enforced by the server. With approval_required set on a provider or on a project (false by default), every signature with that provider needs an approved request first, on every signing route, raw signing and signtool through the dlib included, and a signature asked for without one is answered with 403 approval_required. GET /api/v1/approvals/{id} reports the state of a request. An approval is single use: executing one that has already signed answers 409 approval_already_used, a request that has not been approved answers 409 approval_not_approved, and a signing attempt that fails does not use the approval up. The command line tool has a new approval verb to request, check and execute an approval, and sign --approval --wait asks for the approval, waits for it and then signs. Exit code 10 means the approval is still pending, and 11 means it was denied, has expired or was already used.
- NewSignature server: default timestamp servers with fallback. The new timestamp block lists the servers used when a request does not name one (timestamp.servers, http://timestamp.digicert.com and http://timestamp.sectigo.com by default, 30 seconds each), and a provider can replace that list with its own tsa_urls. The servers are asked in order, and a server that fails or returns a token that does not check out moves on to the next one. A request can still give its own tsa_url, or send no_timestamp to sign without one. On the Authenticode, MSI, APPX, catalog and PowerShell routes level is now optional, and without it the server decides. Every failed server is written to the log and counted in the new sgcsign_tsa_failures_total metric, and the dashboard shows the list in use.
- NewThe command line tool has a new timestamp verb. sgcsign timestamp adds an RFC 3161 timestamp to a file that is already signed, the way signtool timestamp does, for a program or a dll, an installer, a catalog or a PowerShell script. It talks to the timestamp server directly, so no sgcSign server and no API key are needed, and --tsa can be repeated to give fallbacks. The library has the same as the new TimestampSignature and TimestampBytes methods of the Authenticode signer.
- NewSignature server: encrypted backups. The new backup block (off by default) writes an archive every 24 hours by default and keeps the 14 newest. Each archive holds the configuration, a consistent snapshot of the database, the master key and every key and certificate file the configuration refers to, all protected by a passphrase. The admin console has a Backup page with a Backup now button, and a failed backup is reported in the audit log, by webhook and by email. The new --archive switch creates, verifies, extracts and restores an archive from the command line. A restore on another machine seals the master key for that machine, so moving the server keeps the encrypted secrets and the two-factor enrollments working.
- NewSignature server: email notifications. The new smtp block configures the mail server, and on Windows the connection uses the Windows TLS stack (SChannel) by default, so no OpenSSL DLLs are needed. The notifications block says who receives the emails and which ones are sent: security events such as account lockouts, two-factor changes and password changes, failed backups and certificate expiry warnings (all on by default). Each console user can have an email address, the emails are sent in the background so a slow mail server never holds up the console, and the new Email page has a Send test email button.
- NewSignature server: certificate expiry monitoring. The server checks the certificates it holds when it starts and then once a day, and warns when one is 30, 14, 7 and 1 days from expiry (notifications.expiry_days), once for each threshold and certificate. Each warning is a cert.expiring webhook, an audit entry, a log line and, when email is configured, an email. The dashboard has a Certificates card, the providers page shows when each certificate expires, and the new sgcsign_certificate_not_after_seconds gauge lets a monitoring system raise its own alert.
- NewPKCS#11: a guard against locking a token with a wrong PIN. After MaxPinAttempts incorrect PINs in a row (2 by default) the provider refuses every further login without sending it to the token until ResetPinGuard is called, so a wrong PIN in a configuration or a script can no longer use up the retries of a smart card or a USB token. The token flags are checked before every login, and when the token says the next wrong PIN locks it, the login is refused unless AllowFinalPinTry is True (False by default). Signature server: the same is set per provider with max_pin_attempts and allow_final_pin_try, the count is kept when the provider is rebuilt, and Reset PIN guard on the providers page clears it.
- NewThe command line tool can now remember its settings. sgcsign config set, get, unset and list save the server and the other options in a profile, sgcsign auth set-key stores the API key (read from standard input when no key is given, so it stays out of the shell history), and --config-profile picks a profile other than the default one. The stored key is protected for the current user, with DPAPI on Windows and a file only that user can read on Linux and macOS. An option given on the command line still wins over the saved value, and the .NET tool reads the same profiles.
- NewSignature server: a Windows installer. sgcSignServer_Setup.exe installs the server as a Windows service, asks for the password of the first administrator and for the port (8443 by default), opens that port in Windows Firewall, and offers three choices for TLS: a self-signed certificate generated on the spot (the default), an existing PFX file, or plain HTTP for an isolated test machine. The database and the other data go to ProgramData\eSeGeCe\sgcSign Server, which only SYSTEM and Administrators can open. It also runs silently, and it upgrades and uninstalls an existing installation. For a server installed without it, the new --init-admin switch creates the first administrator from an elevated command prompt.
- NewAuthenticode page hashes, the same as signtool sign /ph. Turn on PageHashes and the signature also carries one hash for every 4 KB page of the file, so Windows can check each page as it loads it instead of the whole file, which kernel drivers need when Memory integrity is on (off by default). The result is byte for byte what signtool writes, for SHA-1, SHA-256, SHA-384 and SHA-512. Requested by a customer, thank you.
- NewSignature server: page hashes on both Authenticode routes. The hash route takes the page hash table in a new page_hashes field, so a driver still never has to be uploaded, and the whole file route takes page_hashes=true. The command line tool adds them with --page-hashes, which also works with --append, --tsa-direct and --add-cert.
- FixedA key provider that was never loaded now says so straight away. Asking the PFX, PEM, CSC, Azure Trusted Signing, Certum SimplySign or HashiCorp Vault provider for its certificate before the call that loads it used to hand back an empty certificate, which only failed much later, far from the missing line, and the Windows certificate store provider refused with a general error that named no call. All of them now raise EsgcSignKeyProviderNotLoaded, with a message naming the call to make, for example LoadFromFile, Connect or SelectCertificateBySubject. Certum SimplySign also raises it when asked to sign with no certificate selected, where it used to raise a general error. A provider that is configured and never used, such as one dropped on a form, behaves exactly as before.
- FixedA PFX provider whose reload fails no longer carries on with the certificate it held before. A reload from a file that does not exist, or from empty data, used to leave the previous certificate loaded and still signing. A reload with a wrong password already refused to sign, but the Certificate property still showed the previous certificate, so a program displaying or logging it saw the wrong one. In both cases the provider is now left not loaded, with the previous certificate cleared. Certum SimplySign had the same problem when SelectCertificate failed: it kept the new certificate id, so it went on signing with that certificate's key while still returning the previous certificate, and a document could carry one certificate over a signature made by another. A failed selection now leaves no certificate selected, and a selection answered with a subject but no certificate no longer returns the previous certificate either.
- FixedLoading a certificate from a PKCS#12 file could leave a copy of its private keys in the Windows key store. When Windows refused to keep the keys in memory, the load fell back to an import that writes them into the user profile, and nothing ever removed them. The keys are now kept in memory the same way the PFX provider keeps them, and anything that fallback writes is deleted before the load returns.
- FixedThe command line tool now checks, when --cacert is given, that the server certificate was issued for the host name or IP address in --server. Until now any certificate that CA had issued was accepted for any server. Without --cacert, the trust store the indy transport finds on its own already checked a host name and now checks an IP address too. Upgrade note: a server whose certificate does not carry the address it is reached by is now refused, with --cacert, and on the default trust store when the server is given by IP address. A certificate refused over the indy transport now exits 7, the TLS error code, instead of 4.
- FixedThe command line tool now follows a redirect only when it stays on the same scheme, host and port as the server. Any other redirect is refused before a request is sent there and exits 1, on every verb, health included, so the API key is never sent to another host. Until now both transports followed a redirect to any host and sent the API key along with it.
- FixedThe command line tool now gives the right exit code for a response that carries nothing it can use. On the Authenticode route Windows uses by default, a response without a signature exits 5, as the upload route already did, instead of 1. An empty or unreadable response exits 4 for health, which used to report the server as up and exit 0, 1 for keys, which used to print an empty list and exit 0, and 1 for verify, which used to exit 6 as though the signature were invalid.
- FixedThe command line tool built for a platform other than Windows now refuses --prehash, --append, --tsa-direct and --add-cert with --format authenticode, with exit code 2 and before any request is sent. Those options need the local pre-hash route, which sgcsign.exe has on Windows only, and such a build used to upload the whole file and drop them without a word. The .NET tool takes that route on every platform.
- FixedThe command line tool now applies SGCSIGN_TSA_DIRECT only to a run that asks for a timestamp through --tsa. The variable used to override --no-timestamp and fetch a timestamp anyway, and a run without --tsa had the server sign and then failed with exit code 5, so a variable set for a whole build agent broke every job on it that gave no --tsa. Those runs now behave exactly as they do without the variable, and --tsa-direct keeps its own checks.
- FixedThe command line tool now treats a response that ends before the length the server announced as a server that cannot be reached, exit code 4, on both transports and for every verb, instead of using the part that arrived. The health verb also exits 4 for an answer that is a JSON array, which it used to report as a healthy server, and for a server URL with no host, which the WinHTTP transport used to stop on with a fatal error and exit code 1.
- FixedThe command line tool now refuses an API key that contains a line break or any other control character before any request is sent, with exit code 2 when it comes from --apikey and 1 when it comes from SGCSIGN_APIKEY, and the message never repeats the key. Such a key used to be sent as it was, and a line break added a header line of its own to the request. A --server port above 65535, a port of 0 and a port that is not a number are refused too, with exit code 4 on every verb. Both transports used to wrap the number around 65536, so port 99999 connected to port 34463, and the Windows transport sent the API key there as well.
- FixedThe command line tool now refuses a server URL whose scheme is not http or https, such as ftp://, before any request is sent, with exit code 4 on every verb and both transports, and a URL with a scheme and no host, such as http://, exits 4 the same way on both. The Windows transport used to read the scheme as a host name, so wherever a host of that name resolved the request went there with the API key, and the indy transport sent the request as plain http to the host and port the URL named. A server URL with no scheme at all, such as localhost:8443, is now refused the same way, where the Windows transport used to send the request, API key included, over plain http. Upgrade note: a script that gives the server without http:// or https:// must now add it. Spaces before and after the server URL are now trimmed, backslashes after the scheme are accepted as slashes, so http:\\host is read as http://host, and a server given as a bracketed IPv6 address, such as http://[::1]:8443, now works on the Windows transport, which could not connect to it.
- FixedSignature server: the admin console now reports a duplicate username with a clear message instead of the raw database error, including a name that differs from an existing one only in case and two administrators creating the same name at once. A project slug created twice at once is reported the same way, and any other database failure behind a console action or page now shows a short message pointing to the server log, where the detail is written.
- FixedSigning an MSIX or APPX package with a certificate that does not match the package no longer produces a package Windows refuses. Windows requires the Publisher written in the package manifest to be exactly the subject of the signing certificate, and rejects the whole package when the two differ, which shows up as a package with no signature at all and one that looks corrupted. sgcSign signed it anyway and reported success. It now stops and names both values, and the server answers 400 instead of handing back a package that will not work. A new ValidatePublisher property (True by default) turns the check off, and two new helpers, sgcAppxReadPublisher and sgcAppxDNMatches, let you compare the two yourself before signing. Reported by a customer, thank you.
- FixedSignature server: the admin console error page for an unexpected failure now always shows a short message pointing to the server log and never the text of the error, which is written to the log instead, and writing to that log never holds up the console, even when nothing is reading the server output. The audit log page now also shows the message a console action sends back to it, so a failed audit chain check reports that the audit log could not be read, where the page used to show nothing.
- FixedThe PEM key provider now loads an EC private key in the traditional OpenSSL form, the file that starts with BEGIN EC PRIVATE KEY, which is what openssl ecparam -genkey writes. Only the PKCS#8 form, BEGIN PRIVATE KEY, was accepted, and the traditional form failed with "Failed to decode private key". It now loads from a separate key file and from a combined certificate and key file, and signs exactly as a PKCS#8 EC key does. Such a key can now also be saved to a PFX/P12 file with SaveToP12 and SaveToP12Bytes.
- FixedThe PEM key provider can now save an encrypted PKCS#8 key, the file that starts with BEGIN ENCRYPTED PRIVATE KEY and is loaded with PrivateKeyPassword, to a PFX/P12 file. SaveToP12 and SaveToP12Bytes passed the still encrypted key to the export and failed with NCryptImportKey failed: NTSTATUS=$8009310B. The decrypted key is now exported, for RSA and EC keys, and the key held in memory is overwritten when the provider is reloaded or freed. Calling LoadCertificateOnly after LoadFromFile also no longer keeps the previous private key, which let SaveToP12 pair the new certificate with the old key.
- FixedThe PFX key provider can now sign with an EC key. A PFX or P12 file holding a P-256, P-384 or P-521 key was reported as RSA-SHA256 and every signature failed with NCryptSignHash error $80090027, so no XAdES, CAdES, PAdES or Authenticode signature could be made with it. The provider now reads the key type from the key itself, reports ECDSA with the configured digest, and signs with ECDSA through SignData and SignDigest, exactly as the PEM provider does. This includes a P12 written by the PEM provider with SaveToP12, and a certificate with an EC key issued by an RSA CA, which is reported by the algorithm of its own key.
- FixedThe Windows certificate store key provider, TsgcWindowsCertStoreProvider, can now sign with a certificate whose private key is EC (P-256, P-384 or P-521). It reported RSA and every signature failed with 0x80090027. It now reads the key type from the key itself, reports ECDSA with the configured digest, and signs with ECDSA through CNG, exactly as the PEM and PFX providers do.
- FixedSigning with an EC key set to SHA-1 now produces a valid signature. The PEM, PFX, PKCS#11 and Windows certificate store providers reported such a key as ECDSA with SHA-256, so XMLDSig and XAdES declared ecdsa-sha256, and CAdES, PAdES and timestamp requests declared ecdsa-with-SHA256, over a signature made with SHA-1, which did not verify. TsgcSignatureMethod has a new value, smECDSA_SHA1, added at the end so the existing values keep their ordinal numbers, and the signers now declare http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1 and ecdsa-with-SHA1 (1.2.840.10045.4.1) for it.
- FixedNuGet packages and CMS signed timestamp requests could carry a signature that does not verify. TsgcNuGetSigner.Hash and TsgcTSAClient.SignOptions.HashAlgorithm were written into the signature, while the PEM, PFX, PKCS#11 or Windows certificate store provider kept signing with its own HashAlgorithm, so a SHA-384 package on a provider left at SHA-256 declared one digest over a signature made with the other, with RSA and EC keys alike. Both signers now hand their digest to the provider for the signature and restore the provider setting afterwards, as CAdES, PAdES and Authenticode do, and a provider that only signs with SHA-256, such as the cloud providers, now refuses any other digest with a clear error.
- FixedAn RSA key set to SHA-1 was declared as rsa-sha256 by the ClickOnce signer and by TsgcXMLDSigEngine, so the manifest named one digest over a signature made with another and did not verify. Both now declare http://www.w3.org/2000/09/xmldsig#rsa-sha1. The ClickOnce signer also hands its Hash to the key provider before signing, as the XMLDSig signer does, so SHA-1, SHA-384 and SHA-512 manifests verify whatever the provider was set to, and a provider that only signs with SHA-256 refuses the other digests with a clear error.
- FixedThe Google Cloud KMS provider reported every key as RSA with SHA-256 and always asked Cloud KMS for a SHA-256 signature, so an EC P-256 key was labelled RSA and an RSA-PSS key was labelled PKCS#1 v1.5, producing signatures that fail validation with no error raised. Connect now reads the algorithm of the key version from the public key answer, and each request carries the digest that key version requires. EC_SIGN_P256_SHA256 is reported as ECDSA with SHA-256 and its signature is returned as the raw r||s pair the other providers return. EC_SIGN_P384_SHA384 (ECDSA with SHA-384) and RSA_SIGN_PKCS1_4096_SHA512 (RSA with SHA-512) sign through SignDigest only, because the signers declare SHA-256 for a cloud provider. RSA-PSS, raw PKCS#1, secp256k1, Ed25519 and post-quantum key versions are refused at Connect, a digest the key version does not sign is refused with a message naming its algorithm, and changing the key after Connect now requires a new Connect.
- FixedVSIX packages could carry a signature that does not verify. The VSIX signer declared rsa-sha256 for an RSA key set to SHA-1, and it never handed its Hash to the key provider, so a SHA-1, SHA-384 or SHA-512 package on a PEM, PFX, PKCS#11 or Windows certificate store provider left at another digest declared one digest over a signature made with another, and on the signature server it signed with whatever digest the previous request had left. The signer now declares http://www.w3.org/2000/09/xmldsig#rsa-sha1 for SHA-1, hands its Hash to the provider for the signature and restores the provider setting afterwards, and a provider that only signs with SHA-256, such as the cloud providers, now refuses any other digest with a clear error, which the server answers with 400.
- FixedTsgcVSIXSigner accepted an EC key and wrote an ECDSA signature under an RSA SignatureMethod, so a VSIX signed with a P-256, P-384 or P-521 key from a PEM, PFX, PKCS#11 or Windows certificate store provider failed every verifier. VSIX signing is RSA only, so an EC key is now refused with a clear error before the key provider is used, and /api/v1/sign/vsix answers 422 sign_failed.
- FixedSignature server: saving providers, webhooks or the firewall from the admin console could delete the configuration file. The file was deleted before the new copy was moved into place, so when that move failed the server was left with no configuration and could not be restarted. The new copy now replaces the file in a single step, a failed save leaves the file exactly as it was, and the console says so.
- FixedSignature server: a firewall change saved from the admin console that could not be applied to the running server left the server with no firewall at all. The new rules are now built before they replace the running ones, so when applying them fails the previous rules stay in force and the console says so.
- FixedSignature server: when a firewall change could not be written to the configuration file, the admin console showed the rejected values as if they had been saved. It now shows the stored rules.
- FixedSignature server: the Hash algorithm setting of a PFX provider (hash) had no effect. It is now applied to the provider, an unknown value makes the provider unavailable with a configuration error, and a sign request that leaves out hash (or alg on the authenticode, msi and raw hash routes) is signed with it. Every other provider defaults to SHA-256, an explicit hash or alg still wins, MSIX and APPX keep SHA-256, and XAdES keeps the digest its profile fixes.
- FixedSignature server: CAdES and PAdES signed every document with SHA-256 whatever the request asked for. They now sign with the requested digest, and a cloud provider that only signs SHA-256 answers 400 instead of signing with another digest than the one requested.
- FixedSignature server: the AWS KMS provider ignored its certificate file (cert_file), and a Google Cloud KMS provider had no way to receive one, so both could only sign through /api/v1/sign/raw. Both now read the optional cert_file before connecting, and a missing or invalid file makes the provider unavailable with a clear error. The AWS KMS, Google Cloud KMS and HashiCorp Vault providers accept the certificate file as PEM or DER; a PEM file made the Vault provider fail with "Invalid certificate: expected SEQUENCE".
- FixedSignature server: the admin console labelled the Vault provider certificate as a CA certificate file. It is the signing certificate paired with the Vault key, and the field is now labelled Certificate file path (optional).
- FixedSignature server: the OpenAPI description of /api/v1/keys now says it lists every configured provider without a project filter, and the sign routes no longer declare sha256 as the default hash, since the provider default applies.
- FixedPKCS#11: the PIN, the certificate label filter and the token and slot description fields were handled in the code page of the machine. PKCS#11 defines all of them as UTF-8, so a PIN or a label holding an accented character was sent as the wrong bytes and a token label came back unreadable. They are now encoded and decoded as UTF-8.
- FixedThe Authenticode digest of a Windows Installer package that holds storages inside it was computed in the wrong order, so the signature written over such a package was one Windows refused with "the digital signature of the object did not verify", and a package somebody else had signed was reported as modified when it was not. Every .msp patch package holds storages, and so does an .msi carrying an embedded transform. The streams and the storages of a storage are now hashed together in name order, not every stream first and every storage afterwards, which is what the digest inside the signature of fifteen packages signed by Microsoft and Adobe says. An .msi with no storages inside it is unaffected and its digest is unchanged.
- FixedSignature server: timing no longer goes wrong once Windows has been running for 49.7 days, when its millisecond counter wraps back to 0. Updating or removing a key provider waits for a signature in progress to finish, and around the wrap that wait gave up at once and reported the provider as busy, could last for weeks, or, in a build with overflow checking, raised an error. The duration reported for a signature that crossed the wrap was 0. Both now measure the time elapsed in a way that survives the wrap.
- FixedPKCS#11 on a 64 bit platform that is not Windows. The Cryptoki types were declared with the Windows widths on every platform, so on 64 bit Linux, macOS and Android the token information call wrote 48 bytes past the end of the buffer and the slot list call ran past the end of the array, which brought the process down. They now follow the ABI of the platform. Windows is unchanged byte for byte. Off Windows the module is loaded with the platform loader and a failure carries the message the loader gave, and on iOS a module is refused by design with a clear message.
- FixedOff Windows the library recorded local time as UTC with a zero offset, so a CAdES signing time, a XAdES signing time, an AWS request date and a VSIX timestamp were all out by the machine's offset from UTC. The time is now read from the system in UTC, daylight saving included. Windows was always right and is unchanged.
- FixedOff Windows several checks were not performed at all. Verifying a signed DER structure, verifying a certificate signature, verifying a DER signature, the random value the server uses for authentication and the OCSP nonce were all stubs that did nothing or refused, and the certificate a signature has to be checked against could not be looked up. They all work now, and the issuing certificate is looked for in SSL_CERT_FILE and SSL_CERT_DIR first, then in the distribution CA bundles on Linux, the system and Homebrew bundles on macOS and the system anchor directories on Android. iOS has no such file to read and the API says so.
- FixedCertificates whose key is on a Brainpool curve (brainpoolP256r1, brainpoolP384r1 or brainpoolP512r1), such as the ones used in the German gematik health network, could not be verified. VerifySignatureBy and MatchesIssuer with the signature check turned on returned False even when the issuer was the right one. These signatures are now verified on every platform, on Windows 10 and later through CNG. Signing with a Brainpool key is still not supported and is refused with a clear error. Reported by a customer, thank you.
- FixedOn Linux, the response headers the HTTP transport hands back, the ones sgcSignHTTPHeaderValue reads, lost the SameSite, Max-Age and Expires attributes of every Set-Cookie line and could end with empty lines. They now carry the Set-Cookie lines exactly as the server sent them. On macOS, iOS and Android each line is still rebuilt from the parsed cookie, which now includes Expires but cannot carry SameSite.
- FixedThe license tool could not issue a license anywhere but Windows, it stopped with "failed to build BCRYPT_RSAFULLPRIVATE_BLOB". It now signs through the library's own cryptography on every platform, and licenses issued before still verify. The issued_at time written into a license was the local time marked as UTC, it is now real UTC.
- FixedAsking the server to check a Windows Installer package, an MSIX or APPX package or a catalog reported the file as not valid instead of checking it, even though signing those formats worked. All three are now checked properly, on every platform. Sending a file that is not what the request says it is now answers with an error that says so, instead of reporting a good signature as broken.
- FixedA catalog file could not be checked by the library at all. It was read as if it were a program file and the check failed. A catalog is now recognised and its signature and content list are checked.
- FixedSignature server admin console: a firewall rule that is not valid showed the general error page instead of saying what was wrong with it, and could leave the page unusable. Deleting a key, a user or a project that does not exist, or enabling a key that does not exist, reported success although nothing had changed. Both are fixed, and the console now says what went wrong.
- FixedSigning with a version 1 certificate, the kind without extensions that is still common for test and internal certificates, produced CAdES, Authenticode, NuGet and signed timestamp request signatures that no verifier could read, OpenSSL stopped with a parse error on the issuer. The certificate's validity dates were written where its issuer name belongs. Version 1 certificates are now read correctly, and the same fix applies to OCSP revocation checks against a version 1 issuing certificate and to the signature verifier. PAdES was not affected.
- FixedTsgcCatalogSigner, TsgcMSISigner, TsgcAppxSigner and TsgcPowerShellSigner could not be used through a variable of type TsgcAuthenticodeSigner. SignFile, SignStream and SignBytes were not virtual, so a call through the base type ran the EXE signer, which failed on a catalog, an installer, a package or a script with "Invalid DOS signature". They are now virtual and overridden, so each of the four signs its own format whichever type holds it. Code that calls them on the concrete class is unaffected.
- FixedSignature server: the hash routes, /api/v1/sign/authenticode/hash, /api/v1/sign/msi/hash and /api/v1/sign/appx/hash, now send the X-Sgcsign-Duration-Ms and X-Sgcsign-Signer-Subject headers the upload routes already send. The command line tool read both, so after a hash route signature it printed "Duration: ms" with no value, and on the authenticode route an empty signer. Both are now filled in, and the OpenAPI description declares the two headers on the hash routes. The signer_subject field of the JSON body is unchanged.
- FixedSignature server: a call refused by the per minute limit or by the total call quota no longer uses up the daily quota of its API key. Until now every refused call was still counted for the day, so a key that reached its per minute limit ran out of its daily quota early, for example after 40 calls on a quota of 60. Reported by a customer, thank you.
- FixedTimestamps: when a timestamp server refused a request and wrote the reason with characters that are not valid UTF-8, for example Polish letters in an older code page, the reason was lost. On Windows the call stopped with a text decoding error instead of the timestamp error, and on Delphi 7 and Linux the error said only "rejection". The reason given by the server is now always part of the error message.
- FixedSignature server: the Create User form of the admin console offered only the admin, operator and readonly roles, so a project admin or a delegated administrator had to be created with another role and changed afterwards. It now offers every role, project_admin and delegated_admin included. Requested by a customer, thank you.
- FixedXML signature verification now takes the SignedInfo, the References and the SignatureValue from a single parsed document tree. Before this, a crafted document could make the verifier check one SignedInfo while digest checking different References, or hide a Reference URI inside a comment, and still be reported as valid. A document with more than one SignedInfo, with duplicate Id values, or that is not well formed is now rejected.
- FixedXML signature verification no longer removes a plain element named Signature that is not in the XML Signature namespace. Documents that carry such a business field now verify correctly.
- FixedEU trust lists: the certificate used for the pinned pivot and for the member state identity check is now always the one inside the signature that verified the list, never a certificate found elsewhere in the document, for example inside a comment. A list with more than one top-level signature is now refused. Without RequirePinnedPivot a list is only integrity checked, not authenticated, and the documentation now says so.
- FixedLTV verification no longer judges an embedded OCSP response against the SigningTime written by the signer, since a signer holding a revoked key could backdate that value. Without a verified timestamp the current time is used instead, so an old embedded response can no longer skip the live revocation check.
- FixedAuthenticode verification now checks the certificate table strictly and reports a file as tampered when data is hidden in it outside the signature. It previously reported such files as valid.
- FixedCertificate chain building now always requires every issuing certificate to be a CA (basicConstraints cA, and keyCertSign when keyUsage is present), honours pathLenConstraint, checks issuer validity, and treats a critical extension it does not process, including a critical nameConstraints, as making the chain untrusted, regardless of the CheckKeyUsage setting. Before this, any end-entity certificate issued under a trusted CA could itself issue certificates that chained as trusted. X509 certificates gained PathLenConstraint and UnsupportedCriticalExtension properties.
- FixedThe XML parser now limits element nesting to 1024 levels. A deeply nested document could previously overflow the stack and terminate the process.
- FixedKSeF: extracting a downloaded pack now rejects entry names that would write outside the destination folder, checks every name before writing anything, and creates folder entries correctly.
- FixedKSeF: a malformed JSON array in a server response no longer makes the parser loop forever. It now raises a parse error instead.
- FixedThe PE parser now uses overflow safe bounds checks. A crafted header offset could previously pass the old checks and cause an access violation when signing or verifying.
- FixedSignature server: an admin console session that reached its maximum lifetime, or that was ended from another tab, could previously still be used. Requests now work on a private copy of the session, and an expired session is sent back to the login page.
- FixedXMLDSig and XAdES signing no longer remove an existing signature, or any element named Signature, from the document being signed. For an enveloped signature over the whole document, the digest now matches the output, so signing a document that already contains such an element produces a valid signature.
- FixedSigning a file in place, covering Authenticode, PowerShell, catalog, MSI, MSIX and APPX, ClickOnce, NuGet, VSIX and PDF, now writes to a temporary file and replaces the target only once the write has succeeded, so a failed write can no longer leave the original truncated. NuGet, VSIX, ClickOnce and PDF can now be signed in place as well.
- FixedSigning with a key provider shared by several threads could produce an invalid signature with no error, because each signer set the provider hash algorithm, signed and restored it without a lock, so one thread could sign with the digest another thread had just set. Signers now call the new SignDataWithHash method of the key provider, which sets, signs and restores the hash under a lock of the provider, and they no longer leave their digest behind in the provider. Code that shares a provider between threads should call SignDataWithHash instead of setting HashAlgorithm and calling SignData.
- FixedSignature server: every admin console page showed its content below the menu instead of beside it, after the HTML components started drawing a menu that folds into a drawer on small screens by default. The menu is drawn the way the console expects again, and a page can no longer be broken this way by a future change in how the menu is drawn.
- FixedPAdES: PDFs saved with a cross-reference stream (PDF 1.5 and later) could not be signed and failed with "cannot locate the document Catalog (/Root)". This is the default for files made from Microsoft Office through Acrobat PDFMaker, among others. They now sign, including LTV and archive timestamps, and the update written by the signer uses the same kind of cross-reference as the original file, so strict validators see a consistent structure. Reported by a customer, thank you.
- FixedPAdES: the update written by the signer now keeps the document information and the document ID of the original file, as the PDF standard requires.
- FixedPAdES: in a PDF whose form dictionary is stored as a separate object, the new signature field was not added to the form, so some viewers did not list the signature. The same applied to the document timestamp. Both are now added.
- FixedPAdES: the signature widget is now placed on the real first page of the document. It used to go to the first page object found in the file, which in some files is not page 1.
- FixedSignature server: audit.retention_days was never applied, so the audit log only ever grew. The retention now runs when the server starts and then once a day, and the log stays verifiable: the entries are checked before they are deleted, nothing is deleted when the hash chain is broken, and every purge is itself written to the log as audit.purge. Upgrade note: with the default of 365 days, the first start after upgrading deletes every audit entry older than one year. Set audit.retention_days to 0 before upgrading to keep every entry.
- FixedSignature server: the Windows server needed a sqlite3.dll that was never shipped with it, so it could not open its database on a machine that did not already have one. SQLite is now built into the server and no DLL is needed.
- FixedSignature server: CAdES signatures were never timestamped, even when a timestamp server was given. They are now CAdES-T whenever the request, the provider or the server configuration supplies a timestamp server, and CAdES-BES otherwise.
- FixedSignature server: a tsa_url sent with a XAdES profile that does not timestamp was ignored without a word. It is now refused with 400 timestamp_not_supported, so a caller that expects a timestamp learns that it will not get one.
- FixedSignature server: Windows paths written with forward slashes in the configuration file, such as C:/sgcsign/data/sgcsignserver.db, are now accepted.
- BreakingSignature server: an approval can now be used only once. Executing an approval that has already signed answers 409 approval_already_used, where it used to sign again, so a script that reused one approval for several files has to request one for each signature.
- BreakingThe sign verb of the command line tool no longer forces a signature without a timestamp when --tsa is not given. The server now decides, so it timestamps with the tsa_urls of the provider or the default timestamp servers. Add --no-timestamp to keep the old behaviour.
- BreakingSignature server: a tsa_url on a XAdES profile that does not timestamp now fails with 400 timestamp_not_supported instead of being ignored. Remove the tsa_url or choose a profile that timestamps.