Skip to content

ACTALIS (ACe 2025) Italian CNS card not working #3804

Open

Description

@matteobin

Describe the bug

I can't use my new ACTALIS (ACe 2025) Italian CNS card with Mozilla Firefox to authenticate to government sites.

I would be happy to sponsor some work on this issue.
Do OpenSC developers accept donations?

By the way, I've even started a thread on opensc-devel mailing list, since I do prefer mailling lists to web interfaces.
https://sourceforge.net/p/opensc/mailman/opensc-devel/thread/20260815060545.matteobin.GA2904%40mail.tiepi.it/#msg59373942
So I'll write this issue updates on the mailing list as well.

Steps to reproduce

Some basic tests using pkcs11-tool:

$ pkcs11-tool -l -t

Using slot 0 with a present token (0x0)
Logging in to "MATTEO BINI".
Please enter User PIN:
error: PKCS11 function C_Login failed: rv = CKR_USER_PIN_NOT_INITIALIZED (0x102)
Aborting.

I got the card ATR using opensc-tool:

$ opensc-tool -a

Using reader with a card: bit4id miniLector-EVO 00 00
3b:ff:18:00:ff:81:31:fe:4d:00:6b:04:04:b8:5b:01:f1:01:43:4e:53:10:31:80:9d

The driver opensc uses with the card:

$ OPENSC_DEBUG=9 opensc-tool -n 2>&1 | grep -i itacns

P:31955; T:0x140552569972800 17:05:31.924 [opensc-tool] card.c:337:sc_connect_card: trying driver 'itacns'
P:31955; T:0x140552569972800 17:05:31.926 [opensc-tool] card-itacns.c:144:itacns_init: called

Expected behavior

My previous card used to work, then it expired and I got the new ACTALIS (ACe 2025) model.
https://sistemats1.sanita.finanze.it/portale/elenco-driver-cittadini-modalita-accesso

Actual behavior

I can't login to government sites with Mozilla Firefox and no certificate gets shown in the Security tab of the browser settings window.

OpenSC version

commit a6f4fdc

Operating system

Devuan GNU/Linux 5.0 (Daedalus)

Smart card model or security token

ACTALIS (ACe 2025) Italian CNS

Application used with smart card

Mozilla Firefox

Logs and debug output

Checklist

  • I am using a supported OpenSC version
  • I have searched existing issues to avoid duplicates

Activity

  1. ale-rinaldi commented on Aug 30, 2026

    @ale-rinaldi
    Contributor

    I looked into this a bit. The reason itacns recognizes the card (you get the holder name) but C_Login then fails with CKR_USER_PIN_NOT_INITIALIZED and no certificate shows up is that itacns builds the PIN object together with a key/cert pair: if it doesn't find a certificate, it never creates a PIN either, so the token ends up with a slot but no usable objects.

    On these newer ACTALIS (ACe 2025) cards the CNS certificate and PIN don't sit at the classic MF-relative path (3F00/1100/1101) that itacns probes. itacns can still read the personal-data file (that's where the name comes from), but the CNS objects live behind a dedicated card application, so it finds nothing and bails out — exactly your symptom.

    Before writing a patch it'd help to confirm where the certificate actually lives on your card. Could you run this (no rebuild needed — all in one invocation so it stays in the same card session) and paste the output?

    opensc-tool -s 00:A4:04:00:0C:A0:00:00:05:30:00:0B:10:40:01:02:1A \
                 -s 00:A4:01:0C:02:DA:01 \
                 -s 00:A4:02:0C:02:C0:01 \
                 -s 00:B0:00:00:00
    

    The first line selects the CNS application these cards use; the next two step into the DF/EF where the certificate is expected, and the last reads it. The status words at each step (and whether the read returns a 30 82 … DER blob) will tell us the exact location. If the second or third SELECT returns 6A 82, try DA:11 instead of DA:01 on the second line — there seem to be two slots.

    With that confirmed I can put together a small itacns change and a branch you can build and test.

  2. matteobin commented on Aug 30, 2026

    @matteobin
    Author
  3. ale-rinaldi commented on Aug 30, 2026

    @ale-rinaldi
    Contributor

    Thanks, that's already helpful. My fault on the first line: that SELECT needs a length byte — the 6C 00 is the card asking us to re-send with an Le — so the application wasn't actually selected and the two following SELECTs ran against the wrong context (hence the 6A 82 / 69 86).

    Could you retry with 00 appended to the first line?

    opensc-tool -s 00:A4:04:00:0C:A0:00:00:05:30:00:0B:10:40:01:02:1A:00 \
                 -s 00:A4:01:0C:02:DA:01 \
                 -s 00:A4:02:0C:02:C0:01 \
                 -s 00:B0:00:00:00
    

    If the first line now returns 90 00 (or 61 xx), we're inside the CNS application and the DF/EF selects should reach the certificate — the final read would then start with 30 82 … (a DER blob). If DA 01 still gives 6A 82, try DA 11 on the second line.

    If it still won't come out that way, the most reliable way to pin the exact path is to capture the APDUs the working official software exchanges with the card: on Linux pcsc-spy (from the pcsc-tools package) does exactly that — start it, then read or list the certificate with the vendor software, and paste the trace here. Happy to walk through it.

  4. matteobin commented on Aug 30, 2026

    @matteobin
    Author
  5. ale-rinaldi commented on Aug 30, 2026

    @ale-rinaldi
    Contributor

    Good — the 90 00 on the first line means we're now correctly inside the CNS application, so that part is solved.

    The 6A 82 on DA 01 just means this card lays its files out under that application differently from the older ones I was matching against. Rather than keep guessing file IDs blind (slow and tedious for you), it's much faster to look at what the working software actually does.

    Two options, whichever is easier for you:

    1. The response you redacted after the successful 90 00 select is just the application's File Control Information — file IDs, sizes, access rules; there's no personal data in it — so it's safe to paste. It sometimes lists the EFs directly, which may be all we need.

    2. The definitive way: capture the APDUs the official software exchanges with the card. pcsc-lite ships pcsc-spy for this — it logs every command/response at the PC/SC layer. Roughly: run pcsc-spy in one terminal, then in another read or list the certificate with the vendor tool (or in Firefox via their PKCS#11 module), and paste the log here. I can help get pcsc-spy set up on Devuan if it's not straightforward.

    Either one will show the exact path to the certificate, and from there the itacns change is simple.

  6. matteobin commented on Aug 30, 2026

    @matteobin
    Author
  7. ale-rinaldi commented on Aug 31, 2026

    @ale-rinaldi
    Contributor

    Ha, fair point on "official" software 😄 — and that FCI was useful. The tag 83 02 3F 00 says the application's own file ID is 3F 00: inside the application the card behaves as if it had its own master file. itacns probes the classic CNS certificate path 1100/1101 from the real MF and doesn't find it on your card (only the personal-data 1102 is there) — but the certificate almost certainly lives at that same 1100/1101 inside this application.

    So one more probe — select the application, then walk to 1100/1101 inside it:

    opensc-tool -s 00:A4:04:00:0C:A0:00:00:05:30:00:0B:10:40:01:02:1A:00 \
                 -s 00:A4:01:0C:02:11:00 \
                 -s 00:A4:02:0C:02:11:01 \
                 -s 00:B0:00:00:00
    

    If the final read starts with 30 82 …, that's the certificate.

    If 11 00 returns 6A 82, the card is likely using a PKCS#15 layout under the app instead — in that case this second one-liner reads its EF.DIR, which points to everything:

    opensc-tool -s 00:A4:04:00:0C:A0:00:00:05:30:00:0B:10:40:01:02:1A:00 \
                 -s 00:A4:02:0C:02:2F:00 \
                 -s 00:B0:00:00:00
    

    One of these should reveal where the cert lives, and then the itacns change is straightforward. (pcsc-spy stays the sure fallback, but let's see if we can avoid the proprietary detour.)

  8. matteobin commented on Aug 31, 2026

    @matteobin
    Author
  9. ale-rinaldi commented on Aug 31, 2026

    @ale-rinaldi
    Contributor

    Let's go straight to pcsc-spy then — and no need to install anything: we can pull the module straight out of the .deb and delete it when we're done.

    1. Download and unpack the middleware (no install):

    mkdir -p /tmp/cyb && cd /tmp/cyb
    wget https://swdownload1.agenziaentrate.gov.it/pub/sanita/Cyberneid-Middleware_1.3.9.14_all.deb
    dpkg-deb -x Cyberneid-Middleware_1.3.9.14_all.deb root
    

    2. Start the spy (terminal 1, leave it running):

    pcsc-spy
    

    3. Read the certificate through the vendor module (terminal 2), preloading the spy so pcsc-spy logs every APDU:

    MODULE=$(find /tmp/cyb/root -name 'libcybermw*.so*' | head -1)
    SPY=$(find /usr/lib /lib -name 'libpcscspy.so*' 2>/dev/null | head -1)
    LD_PRELOAD="$SPY" LD_LIBRARY_PATH="$(dirname "$MODULE")" pkcs11-tool --module "$MODULE" -O
    

    -O lists the objects, which makes the module walk to the certificate — exactly the sequence we want. If -O doesn't reach the cert, force the read:

    LD_PRELOAD="$SPY" LD_LIBRARY_PATH="$(dirname "$MODULE")" pkcs11-tool --module "$MODULE" --read-object --type cert --id 01 -o /tmp/cyb/cert.der
    

    Paste the pcsc-spy output here (it's just card commands/responses, no personal data) and the cert path will be obvious — from there the itacns change is trivial.

    4. Clean up — nothing was installed, so just:

    rm -rf /tmp/cyb
    

    (If the module complains it can't find a token or a config, the quickest fallback is to install the .deb with sudo dpkg -i, run the same read, then remove it with sudo dpkg -r. But the extract-only route usually works for reading the cert.)

  10. dengert commented on Aug 31, 2026

    @dengert
    Member

    This issue sounds very much like #3755 But there its the st2022 cards and the issue is more with contactless NFC. But both are Italian CNS cards

  11. ale-rinaldi commented on Sep 1, 2026

    @ale-rinaldi
    Contributor

    @dengert you're right, and I actually suggested to open this one in a comment of the mentioned issue: #3755 (comment)

    Similar issue, but different cards: unfortunately, for mostly historical issues, Italian CNSs are a mess :D I wrote about the topic here: OpenSC/Wiki#38

  12. dengert commented on Sep 1, 2026

    @dengert
    Member

    Nice writeup in the wiki.

    Another OpenSC tool opensc-explorer might be helpful to look at the file structure on the card.

  13. dengert commented on Sep 1, 2026

    @dengert
    Member

    With opensc-explorer can you try something like this with your card. The example is a myeid PKCS15 card.

    $ opensc-explorer
    OpenSC Explorer version 0.26.1
    Using reader with a card: Identiv SCR3500 A Contact Reader [CCID Interface] (54302140601290) 00 00
    OpenSC [3F00]> ls
    FileID	Type  Size
    [5015]	  DF 32767	Name: \xA0\x00\x00\x00cPKCS-15
     2F00 	 wEF   128
    OpenSC [3F00]> asn1 2f00
    61 Application 1  (27 bytes)
       4F Application 15 (12 bytes)
          A0 00 00 00 63 50 4B 43 53 2D 31 35 ....cPKCS-15
       50 Application 16 (5 bytes): 4D 79 45 49 44 MyEID
       51 Application 17 (4 bytes): 3F 00 50 15 ?.P.
    Zero tag, finishing
    

    The 3F00 2F00 is the iso 7816-4 way of listing AID of applets on the card
    It should show your AID
    A0 00 00 05 30 00 0B 10 40 01 02 1A

    Also note that the 3F00 has a DF of 5015 which is also in indicator it is a PKCS15 card
    at least that is what OpenSC uses. But the 2F00 file also lists 3F 00 50 15

    As @frankmorgner pointed out it appears that the "official" driver has some OpenSC code.
    It might be that they are using a PKCS15 file structure.
    You can use opensc-explorer to look around at the file structure.

  14. dengert commented on Sep 1, 2026

    @dengert
    Member

    Downloading the deb file doing a dpkg-deb -R *.deb /tmp/xxx and comparing the strings in libcybermw.so (with s/mw_/sc_/) to a recent opensc-pkcs11.so:

    strings -n 8  usr/local/lib/libcybermw.so | sed -e 's/mw_/sc_/' | sort > /tmp/mw_
    strings -n 8 /opt/ossl-3.5.4/lib/opensc-pkcs11.so  | sort > /tmp/sc_
    comm -12 /tmp/mw_ /tmp/sc_ | wc
      1299    2167   28725
    comm -12 /tmp/mw_ /tmp/sc_ | grep sc_ | wc
        223     243    5071
    comm -12 /tmp/mw_ /tmp/sc_ | grep pkcs15 | wc
        164     239    4270
    

    1299 lines are in both with 233 being name changes of functions starting with sc_ to mw_ and 164 which contain pkcs15
    These include changes from pkcs15init and lots of error messages are the same.

  15. matteobin commented on Sep 1, 2026

    @matteobin
    Author
  16. ale-rinaldi commented on Sep 1, 2026

    @ale-rinaldi
    Contributor

    No worries — pcsc-spy doesn't hook every setup reliably. Let's try capturing one level lower, at the pcscd daemon, which logs the APDUs directly.

    Stop the running daemon and start it in the foreground with APDU logging:

    sudo service pcscd stop        # Devuan; or: sudo systemctl stop pcscd pcscd.socket
    sudo pcscd -f -a               # leave this running; it prints the APDUs
    

    Then, in another terminal, run the same read as before:

    LD_LIBRARY_PATH=/tmp/cyb/root/usr/local/lib pkcs11-tool --module /tmp/cyb/root/opt/Cyberneid/Middleware/libcybermw.so -O
    

    The command/response APDUs will show up in the pcscd terminal — paste those here.

    When you're done, stop the foreground pcscd (Ctrl-C) and bring the normal service back:

    sudo service pcscd start       # Devuan; or: sudo systemctl start pcscd.socket pcscd
    
  17. matteobin commented on Sep 1, 2026

    @matteobin
    Author
  18. ale-rinaldi commented on Sep 2, 2026

    @ale-rinaldi
    Contributor

    I put together a branch that reads the certificate from where your trace shows it — the eSign application at DA01/C001 — selecting the CNS application first so the rest resolves. Could you build it and see if your card works now?

    git clone https://github.com/gridsociety/OpenSC.git
    cd OpenSC
    git checkout itacns-actalis-ace
    ./bootstrap && ./configure && make
    

    Then, with the card in the reader:

    ./src/tools/pkcs15-tool --dump
    

    It should now list a certificate (CNS0). If it does, a quick end-to-end check that the key works:

    ./src/tools/pkcs15-tool --read-certificate 01 -o cns.crt
    head -c 32 /dev/urandom > d.bin
    ./src/tools/pkcs11-tool --module ./src/pkcs11/.libs/opensc-pkcs11.so --login --sign --id 01 --mechanism SHA256-RSA-PKCS -i d.bin -o d.sig
    openssl x509 -in cns.crt -inform der -pubkey -noout > cns.pub   # if it complains, use -inform pem
    openssl dgst -sha256 -verify cns.pub -signature d.sig d.bin
    

    Verified OK means authentication works. Could you paste what --dump lists and whether the signature verifies? That'll tell me if the key wiring is right.

  19. matteobin commented on Sep 3, 2026

    @matteobin
    Author
  20. matteobin commented on Sep 13, 2026

    @matteobin
    Author

    Sorry to bother you, @ale-rinaldi, I know you've already done so much, but I was hoping to be able to fill my 730 tax form, since you made so much progress with my card, before the September 30th deadline.

    Is there something I can do to streamline your work?

    Thank you for the help and patience. :)

  21. ale-rinaldi commented on Oct 12, 2026

    @ale-rinaldi
    Contributor

    Sorry for the long silence, Matteo, and for not getting back to you before your September deadline.

    I've updated the test branch with a candidate fix for CNS login and signing (512357cfe). The local tests pass, but I don't have an ACe2025 here, so your help testing it would be very useful. Could we try these in this order?

    1. Try Cyberneid in Firefox as a reference.

    Close Firefox completely, run firefox -P, and create a separate profile called CNS-test. Close it again and start it from a terminal with:

    LD_LIBRARY_PATH=/tmp/cyb/root/usr/local/lib firefox -no-remote -P CNS-test

    In that profile, open Settings → Privacy & Security → Certificates → Security Devices → Load. Use Cyberneid CNS as the name and the module you extracted earlier as the filename:

    /tmp/cyb/root/opt/Cyberneid/Middleware/libcybermw.so
    

    If that temporary directory is gone, extract the same package again with dpkg-deb -x Cyberneid-Middleware_1.3.9.14_all.deb /tmp/cyb/root. No full installation is needed for this test.

    Keep only that card module loaded in the test profile, leaving Firefox's built-in NSS modules alone. Try the same government site and let us know whether the certificate appears and authentication succeeds.

    2. Try a signature with the updated OpenSC branch.

    Close Firefox and any other card applications, remove and reinsert the card, then rebuild the latest itacns-actalis-ace. From the build directory:

    printf 'ACe2025 OpenSC signing test\n' > ace-test.txt
    openssl dgst -sha256 -binary -out ace-test.sha256 ace-test.txt
    ./src/tools/pkcs15-crypt --sign --key 10 --pkcs1 --sha-256 --input ace-test.sha256 --output ace-test.sig

    Enter only the PIN you already know is correct, at the prompt. If PIN verification fails, stop there rather than trying again. Please share the result or error message. If signing succeeds, you can verify it locally:

    ./src/tools/pkcs15-tool --read-certificate 10 --output ace-cert.der
    openssl x509 -inform DER -in ace-cert.der -pubkey -noout > ace-public.pem
    openssl dgst -sha256 -verify ace-public.pem -signature ace-test.sig ace-test.txt

    You don't need to share your certificate. This candidate currently supports SHA-256/PKCS#1 signing; we'll tackle Firefox compatibility next. The PIN retry count remains unknown for now.

    Optional: a filtered Firefox trace, without saving PIN or certificate data

    One correction to my earlier advice: raw pcsc-spy and pkcs11-spy logs can contain PINs and personal data. A PIN may appear in both hex and ASCII, so please don't capture or post a full login trace.

    For a small diagnostic summary of the Cyberneid test, close Firefox completely and launch it with this command from the OpenSC build directory:

    env -u OPENSC_DEBUG PKCS11SPY=/tmp/cyb/root/opt/Cyberneid/Middleware/libcybermw.so PKCS11SPY_OUTPUT=/dev/stderr LD_LIBRARY_PATH=/tmp/cyb/root/usr/local/lib \
      firefox -no-remote -P CNS-test 2>&1 | \
      awk '/^[0-9]+: C_[A-Za-z0-9_]+[[:space:]]*$/ || /^Returned:  [0-9]+ CKR_[A-Za-z0-9_]+[[:space:]]*$/ || /^\[in\] pMechanism->type = CKM_[A-Za-z0-9_]+[[:space:]]*$/ {print; fflush()}' > cns-api-summary.log

    In Security Devices, unload the direct Cyberneid module and load pkcs11-spy.so from this build instead. Get its absolute filename with:

    readlink -f ./src/pkcs11/.libs/pkcs11-spy.so

    The spy will forward calls to Cyberneid. Try the site, then quit Firefox. The filter saves only function names, return codes and mechanism names, discarding all other output before writing the file. Please check cns-api-summary.log before sharing it: it should contain only lines such as C_Login, CKR_OK and CKM_RSA_PKCS. If it's empty, just tell us; don't fall back to an unfiltered trace.

    Afterwards, unload the spy and reload the direct Cyberneid module for normal use.

    Thanks for your patience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions