Releases: sudondream/cei-pdf-signer
Release list
v0.16-beta
"Move to Applications" is now always available, not just once at startup.
Previous versions asked on first launch and took "no" as final. There was no way to change your mind afterwards — the answer was stored in a file you would have no reason to know about, and the offer never came back.
Now, for as long as the app is running from somewhere other than your Applications folder, a ↑ Move to Applications button sits in the top bar. Click it whenever you like, including long after declining the first prompt.
Worth doing: automatic updates only work from the Applications folder, because that is the only place the app is allowed to replace itself.
Everything else is unchanged
The move itself was fixed in v0.15-beta, and automatic updates have worked since v0.14-beta. Downloads are still verified against their checksum, code signature, developer certificate and Apple's notarization before anything is replaced.
Verifying your download
SHA256SUMS.txt is attached to this release. To check the file you downloaded:
shasum -a 256 -c SHA256SUMS.txt
v0.15-beta
Fixes the "Move to Applications" prompt, which was badly broken in v0.14-beta. If you opened that version straight from your Downloads folder and agreed to move it, the app closed, asked the same question again, and on the second try did not come back at all. Nothing was lost except the app itself — unpacking the download again brought it back — but it was a poor way to be greeted.
If you are on v0.14-beta and it is working, this update installs itself.
What was wrong
macOS runs a downloaded app from a hidden, read-only copy of itself rather than from the folder you can see. Version 0.14-beta tried to install the app from that hidden copy, which macOS deletes the moment the app closes — so by the time the installer ran, there was nothing left to install.
The second problem was quieter. When the app did manage to move itself, it carried its "downloaded from the internet" mark along, and macOS kept running it from that hidden copy even in the Applications folder. The app could not tell it had been installed, so it asked to move again on every launch.
It now finds where it genuinely lives before doing anything, and clears that mark once installed — the same thing that happens when you drag an app to Applications yourself.
Everything else is unchanged
Automatic updates worked correctly in v0.14-beta and are untouched here: the app checks for new versions on startup, and every download is still verified against its checksum, its code signature, the developer certificate, and Apple's notarization before anything is replaced.
Verifying your download
SHA256SUMS.txt is attached to this release. To check the file you downloaded:
shasum -a 256 -c SHA256SUMS.txt
v0.14-beta
This release had a broken "Move to Applications" prompt and its download has been removed. Use v0.15-beta instead.
Opening v0.14-beta from the Downloads folder and agreeing to move it left you with no app — unpacking the download again restored it, but the prompt never worked. Fixed in v0.15-beta.
The app updates itself now. It checks for new versions on startup and tells you when one is available. One click and it downloads, checks the download is genuinely ours, replaces itself and reopens. No more watching this page.
If you close the notice, the offer does not disappear — it moves to a small button in the top bar and waits there until you want it.
You have to install this one by hand
Version 0.13-beta and earlier have no update mechanism, so they cannot notice that this version exists. Download it once the usual way and every version after this arrives on its own.
It offers to move itself to Applications
If you open the app from your Downloads folder, it now asks whether to move itself to Applications, like most Mac apps do. Worth saying yes: automatic updates only work from Applications, because that is the only place the app is allowed to replace itself.
If you would rather not, say no once and it never asks again.
What it checks before replacing anything
An app that can replace itself is an app worth being careful with. Every download is verified four ways before a single file is touched: the checksum published alongside it, the code signature, that it was signed by the same developer certificate as the copy you are already running, and that Apple notarized it.
If any of those fail, nothing is installed and the app you have keeps running exactly as it was — the check happens entirely in a temporary folder, before anything real is modified. A failed update leaves you with a working app, always.
If the app cannot replace itself
Run from inside the archive, or from a folder you cannot write to, the app cannot update in place. Rather than trying and failing, the button changes to "Download" and opens this page instead.
Verifying your download
SHA256SUMS.txt is attached to this release. To check the file you downloaded:
shasum -a 256 -c SHA256SUMS.txt
v0.13-beta
macOS no longer warns when you open this app. It is now signed with an Apple developer certificate and notarized by Apple. Download it, unpack it, drag it to Applications, double-click. That is the whole installation.
Every previous version was refused on first launch with a message about not being able to verify the app is free of malware, and getting past it meant a trip through System Settings that lost a lot of people. That is gone.
The card driver no longer leaves you stuck
The Romanian eID driver can stop responding, and when it did the app simply spun forever — "Detecting…", then a timeout, then "Detecting…" again, with nothing telling you what to do. It now recognises that state and says plainly that the driver has stopped responding and the Mac needs restarting, which is the only thing that fixes it.
Better still, the app is now much less likely to cause it. That failure happens when a program is interrupted in the middle of talking to the card, so closing the app while it is reading your card could leave the driver stuck — for every application on your Mac, until you restarted. Closing now waits for the card to finish, and tells you why it is waiting.
Verifying your download
SHA256SUMS.txt is published alongside the archive. Put both in the same folder and run shasum -a 256 -c SHA256SUMS.txt — OK means the file is byte-for-byte the one published here.
Install
Download the ZIP, unpack it, drag CEI PDF Signer.app to Applications, and open it. Nothing else.
v0.12-beta
Follow-up to v0.11-beta. Recommended for everyone on v0.10-beta or v0.11-beta.
The app could get stuck saying "Reader timeout"
On a machine where the card service was slow to answer, the app cycled between "Detecting..." and "Reader timeout - Click to retry" without ever settling.
Two waits happen inside a single card check: finding the reader, then reading the card's slots. Their limits added up to exactly the point at which the app gives up waiting for its own server, so a check that was merely slow got cut off — and the message shown was the generic timeout rather than the specific explanation the app had prepared. The first wait is now far shorter, leaving a comfortable margin, and a test keeps the two numbers from drifting apart again.
A stray file was being shipped inside the app
Every release since v0.10-beta contained a small leftover link in the root of the application bundle, pointing at a folder on the machine where the app was built. It broke the app's internal seal and exposed that path in every download. The app still ran, which is why it went unnoticed.
The build no longer creates it, and the release checker now refuses any archive that has anything unexpected in the bundle root.
Verifying your download
SHA256SUMS.txt is published alongside the archive. Put both in the same folder and run shasum -a 256 -c SHA256SUMS.txt — OK means the file is byte-for-byte the one published here.
Install
Download the ZIP, unpack it and move CEI PDF Signer.app to Applications.
The first time you open it, macOS will refuse, saying it cannot verify the app is free of malware. That is expected — the app is signed ad-hoc rather than with a paid Apple certificate. To open it: double-click the app, press Done (not "Move to Trash"), then go to System Settings → Privacy & Security, scroll down to Security, and click Open Anyway next to the app name. Confirm, and enter an administrator password if asked. Every launch after that is normal.
A walkthrough with screenshots, and a button that opens that settings pane for you, is on the project page.
v0.11-beta
"PKCS#11 not found" on a machine where the card works fine
A user installed IDPlugManager, confirmed the card was recognised by IDPlugManager itself and by other signing sites, and still got a permanent "PKCS#11 not found" in this application. They tried every library variant under the IDPlug folder and ran commands in Terminal. None of it helped, and none of it could have.
The message was simply wrong. Before touching PKCS#11 at all, the application first checked whether it could see the card reader, and that check relied on opensc-tool — a command-line utility that does not come with macOS. When it was missing, the resulting error was matched against the text not found and displayed as a PKCS#11 problem. So the application pointed at a library path that, on that code path, it never even read. Anyone who did not happen to have OpenSC installed hit this, and the setting they were sent to change had no bearing on it.
Reader detection now goes through the smart card service built into macOS. Nothing beyond IDPlugManager needs to be installed — no Homebrew, no extra package. This is what the installation instructions always promised, and now it is actually true.
Errors now say what is actually wrong
A missing card, an unresponsive card service and a genuinely unreadable PKCS#11 library used to collapse into one misleading message, and some of them were never shown at all. Each is now reported separately and in its own words, with the library-path warning appearing only when that library is really the problem.
Detection is also faster — it now answers in milliseconds instead of launching a separate process — and it can no longer hang indefinitely if the card service stops responding.
Install
Download the ZIP, unpack it and move CEI PDF Signer.app to Applications.
The first time you open it, macOS will refuse, saying it cannot verify the app is free of malware. That is expected — the app is signed ad-hoc rather than with a paid Apple certificate. To open it: double-click the app, press Done (not "Move to Trash"), then go to System Settings → Privacy & Security, scroll down to Security, and click Open Anyway next to the app name. Confirm, and enter an administrator password if asked. Every launch after that is normal.
Right-clicking and choosing "Open" was the shortcut on older macOS versions. Apple removed it, so it no longer works.
A walkthrough with screenshots is on the project page.
If you would rather confirm the download yourself rather than take that warning on trust, SHA256SUMS.txt is published beside the archive. Put both in the same folder and run shasum -a 256 -c SHA256SUMS.txt — OK means the file is byte-for-byte the one published here.
v0.9-beta
Romanian diacritics in the signature
Names containing Romanian letters came out as garbage in the visible signature. Fixes issue #5.
The signature text was drawn with Courier, a standard PDF font limited to the WinAnsi character set. WinAnsi has no s with comma, no t with comma and no a with breve, so the text was written in a different encoding that the font then read one byte at a time. A single Romanian letter anywhere in a name corrupted the entire line, which is why even the letters that WinAnsi does contain, such as a with circumflex and i with circumflex, came out wrong too.
The signature now embeds DejaVu Sans, which covers every Romanian letter in both the correct comma below forms and the older cedilla forms that some certificates carry. The text is also selectable and copies out correctly.
Names such as IOANA ȚUȚU ȘERBAN and ADRIAN BĂNCILĂ ȚÎRLEA now render exactly as written.
The signature font changes from Courier to DejaVu Sans, so signatures produced by this version look different from earlier ones. Documents signed with older versions are unaffected.
Also in this release
Line spacing was increased. The marks under s and t sit below the baseline and previously collided with the line beneath, so a correctly spelled name could still look wrong.
The release build now checks the packaged application before it can be published. It confirms the archive kept its symbolic links and file permissions, that the application starts, and that it can actually find its font once packaged. An application that cannot find its font still runs and still signs, it simply reverts to Courier, so that check exists to stop the same problem shipping unnoticed.
Install
Download the ZIP, unpack it, move CEI PDF Signer.app to Applications, then right click the app and choose Open the first time.
If you are coming from v0.7-beta and it would not open at all, that was a packaging fault fixed in v0.8-beta. See those release notes for details.
Verify the download if you wish:
shasum -a 256 CEI-PDF-Signer-v0.9-beta-macOS.zip
The expected value is in SHA256SUMS.txt.
v0.8-beta
Important for anyone who could not open v0.7-beta
If v0.7-beta failed with "The application CEI PDF Signer can't be opened" or with "ModuleNotFoundError: No module named '_struct'", that was a packaging fault, not a fault in your Mac and not a Python problem.
The v0.7-beta archive was created with a tool that discards symbolic links and file permissions. A packaged macOS app relies on both. The archive shipped with zero of its 45 symbolic links, 29 empty folders where those links belonged, and a main program file that had lost its executable permission. Anything unpacked from it was broken before it ever ran.
This release is archived with ditto, which preserves that structure, and the build now refuses to produce a release archive that does not pass a launch test on a freshly unpacked copy.
Signing reliability
Signing could fail for every document in a batch and still report success while producing an empty ZIP. Three separate causes were found and fixed.
The app used to kill the macOS CryptoTokenKit daemon before every signing call. That took the PC/SC provider down with it and made the card reader invisible to the whole system until the reader was physically unplugged. Measurements showed the kill was never needed, so it is gone, and a test now fails the build if that code ever returns.
The IdPlug driver enumerates card slots progressively rather than all at once. Across runs it reported slot lists of [1], then [1], then [1,2,3], then [1,2]. The old code took a single snapshot and gave up when the signature slot was missing. It now polls until the slot appears, which on a warm reader took about 12 seconds.
Signature placement indexed the PDF page tree as if it were a flat list, which raised IndexError on most real documents. On a 10 page file it failed on 8 pages. Page lookup now goes through pyHanko. A related bug placed signatures roughly 50 points off on A4 without reporting any error.
Saving an empty result set now returns an error instead of writing a ZIP with nothing in it.
New features
Page navigation with a page number field and first and last buttons.
Apply to all pages, which copies the signature box to every page and clamps it to each page's real geometry. This produces one qualified signature covering the whole document plus visual marks on the other pages, rather than signing the same document once per page.
Clear all, which removes every signature box from the selected document at once.
An About section in the sidebar with contact links. Links open in your browser instead of replacing the app window.
Install
Download the ZIP, unpack it, move CEI PDF Signer.app to Applications, then right click the app and choose Open the first time.
Verify the download if you wish:
shasum -a 256 CEI-PDF-Signer-v0.8-beta-macOS.zip
The expected value is in SHA256SUMS.txt.
v0.10-beta
Documents that could not be signed at all
Some PDFs failed with "No key available to decrypt, please authenticate first" and could not be signed. Fixes issue #1.
Those documents are encrypted. What made this confusing is that they open in any viewer without asking for anything, so there is no sign that they are protected. Insurers, banks and public institutions commonly apply an owner password to restrict printing or copying while leaving the opening password empty. The file is still encrypted underneath, and the application was not unlocking it before reading.
It now unlocks such documents automatically, so they sign like any other file. A PDF that genuinely requires a password to open still cannot be signed directly, but it now says so clearly and tells you what to do, instead of failing with a technical message.
Two more problems found behind that one
Both were only reachable on encrypted documents.
Signature placement failed on them, so even once a document was unlocked the signature was never drawn.
More seriously, the protection that stops the application from stamping over a document that is already signed had quietly stopped working on encrypted files. It could have modified an already signed document and invalidated that signature. This never produced an error message, so it would not have been reported.
Install
Download the ZIP, unpack it, move CEI PDF Signer.app to Applications, then right click the app and choose Open the first time.
Verify the download if you wish:
shasum -a 256 CEI-PDF-Signer-v0.10-beta-macOS.zip
The expected value is in SHA256SUMS.txt.
Recent releases
v0.9-beta fixed Romanian diacritics in the visible signature. v0.8-beta fixed the packaging fault that stopped the application opening at all. If you are coming from v0.7-beta or earlier, read those notes too.
v0.7-beta Auto-fix CryptoTokenKit card reader conflict
What's new
The app now automatically handles the macOS CryptoTokenKit conflict that caused it to hang when accessing the smart card reader.
Before: macOS would grab exclusive access to the card reader on insertion, blocking the app. The only fix was manually killing ctkd or restarting the Mac.
Now: If card detection fails, the app automatically kills the CryptoTokenKit daemon and retries — no manual intervention needed.
Note
If the PKCS#11 call hangs (blocks indefinitely rather than erroring), this retry won't trigger. If you still experience hangs, please open an issue. A future release may
preemptively kill CTK before every card access.