Skip to content

Add Romanian eID support via PKCS#11 - #167

Open
GrigorasMateiGS1 wants to merge 4 commits into
web-eid:mainfrom
GrigorasMateiGS1:Add-RoEID
Open

GrigorasMateiGS1 wants to merge 4 commits into
web-eid:mainfrom
GrigorasMateiGS1:Add-RoEID

Conversation

@GrigorasMateiGS1

@GrigorasMateiGS1 GrigorasMateiGS1 commented Sep 16, 2026 •

Copy link
Copy Markdown

Romania's CEI has no public APDU specification, so this adds tier 2 support using the official government middleware (IDPlugManager, by IDEMIA), available at https://hub.mai.gov.ro/aplicatie-cei.

  • Add RoEID to ElectronicID::Type and Pkcs11ElectronicIDType
  • Add ATR (exact match, confirmed via pcsc_scan against a real card, also present in Ludovic Rousseau's public smartcard_list.txt)
  • Add PKCS#11 module paths for Linux, Windows, and macOS, confirmed against real installs on each platform
  • Set allowsUsingLettersAndSpecialCharactersInPin = false (PIN is numeric-only per MAI documentation)
  • Set providesExternalPinDialog = false (confirmed: the middleware does not intercept login, so libelectronic-id must perform it)

Fix: skip certificate objects with empty CKA_VALUE in PKCS11CardManager::tokens(). The CEI exposes an additional "QSCD" application slot reserved for an optional paid qualified-signature certificate. On cards without that certificate (the common case), this slot is present but empty, and reading it previously threw inside make_x509, breaking card detection entirely for any holder without a qualified certificate.

Tested manually against a real CEI card on Linux:

  • getCertificate: passing
  • authenticate: passing
  • signing_SHA256 / signing_SHA3_256: not covered by automated integration tests — no public Romanian test card with a known-safe PIN is available (unlike EstEID/LatEID/FinEID), so a real PIN could not be safely hardcoded in test-signing.cpp. Manually verified signing works against my own card. Flagging this gap for discussion — happy to add a proper case once a safe test approach is agreed.

Known limitation: multiple signing certificates not supported

CEI cards support up to two distinct signing certificates on separate
PIN-protected applications:

  • "Advanced Signature" (free, provisioned by default)
  • "QSCD" / Qualified Signature (paid, optional, separate application)

libelectronic-id's current data model assumes exactly one signing
certificate per card (Pkcs11ElectronicID::signingToken). The
constructor loop silently overwrites signingToken with whichever
signing-classified certificate is enumerated last, with no way for
the caller to select between them.

My card only has the Advanced Signature provisioned, so this isn't
currently reachable in my testing, but it will become a real bug for
any cardholder who has purchased the qualified certificate. I'm
flagging this rather than attempting a fix, since it likely requires
a broader interface change (supporting multiple signing certs per
card) rather than a Romania-specific patch. Happy to discuss/help
design this if it's something maintainers want addressed.

P.S. I also ran the clang-format.sh so there are many spacing changes

Comment thread src/electronic-ids/pkcs11/Pkcs11ElectronicID.cpp Dismissed
@mrts

mrts commented Sep 18, 2026

Copy link
Copy Markdown
Member

Thanks a lot for your contribution, happy to see Romania's CEI support! We will review and merge this as time allows.

@metsma

metsma commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Can you revert non related files formatting

@GrigorasMateiGS1

Copy link
Copy Markdown
Author

Can you revert non related files formatting

I have reverted the formatting

Comment thread src/electronic-ids/pkcs11/PKCS11CardManager.hpp Outdated
Comment thread include/electronic-id/electronic-id.hpp Outdated
@GrigorasMateiGS1

Copy link
Copy Markdown
Author

Is there something left I have to do to have this pull request accepted?

@kristelmerilain

Copy link
Copy Markdown

Your PR has been moved to internal testing. Please note that testing may take some time, so we appreciate your patience. If everything passes testing successfully, we’ll merge it into the main branch.

Thanks again for your contribution and patience!

GrigorasMateiGS1 and others added 4 commits October 23, 2026 11:35
Romania's CEI has no public APDU specification, so this adds tier 2
support using the official government middleware (IDPlugManager,
by IDEMIA), available at https://hub.mai.gov.ro/aplicatie-cei.

- Add RoEID to ElectronicID::Type and Pkcs11ElectronicIDType
- Add ATR (exact match, confirmed via pcsc_scan against a real card,
  also present in Ludovic Rousseau's public smartcard_list.txt)
- Add PKCS#11 module paths for Linux, Windows, and macOS, confirmed
  against real installs on each platform
- Set allowsUsingLettersAndSpecialCharactersInPin = false (PIN is
  numeric-only per MAI documentation)
- Set providesExternalPinDialog = false (confirmed: the middleware
  does not intercept login, so libelectronic-id must perform it)

Fix: skip certificate objects with empty CKA_VALUE in
PKCS11CardManager::tokens(). The CEI exposes an additional "QSCD"
application slot reserved for an optional paid qualified-signature
certificate. On cards without that certificate (the common case),
this slot is present but empty, and reading it previously threw
inside make_x509, breaking card detection entirely for any holder
without a qualified certificate.

Tested manually against a real CEI card on Linux:
- getCertificate: passing
- authenticate: passing
- signing_SHA256 / signing_SHA3_256: not covered by automated
  integration tests — no public Romanian test card with a known-safe
  PIN is available (unlike EstEID/LatEID/FinEID), so a real PIN
  could not be safely hardcoded in test-signing.cpp. Manually
  verified signing works against my own card. Flagging this gap for
  discussion — happy to add a proper case once a safe test approach
  is agreed.
Co-authored-by: Raul Metsma <raul@metsma.ee>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants