Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(pcsc): add opensc load module file #2547

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

innovara
Copy link
Contributor

@innovara innovara commented Nov 1, 2023

On Fedora, and possibly others, there is a file to load the module opensc-pkcs11.so.

In my tests, without this module, you can't unlock a LUKS encrypted volume using a smart card since pscsd is not able to establish any communication with it.

The file simply loads opensc-pkcs11.so with the following syntax:

module: opensc-pkcs11.so

There may be a more efficient way of doing this without having to attempt to add the file from various sources (each distro seems to have this file in different places).

Changes

This pull request adds the installation statements needed to include the file that loads opensc-pkcs11.so on various distributions. I couldn't find where this file lives in Arch Linux. Maybe it's loaded in the configuration directly.

Checklist

  • I have tested it locally
  • I have reviewed and updated any documentation if relevant
  • I am providing new code and test(s) for it

@github-actions github-actions bot added the modules Issue tracker for all modules label Nov 1, 2023
Copy link
Member

@aafeijoo-suse aafeijoo-suse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for looking into this!

The current upstream rule is to follow only other upstreams, so remove all the comments and add only what the OpenSC packaging says: /usr/share/p11-kit/modules/opensc.module

https://github.com/OpenSC/OpenSC/blob/6d7fad101812dbcbde4a3ff069281a359fc54d1f/packaging/opensc.spec#L140

I got a smart card reader and a card with certs, so I'll test that this is working fine. One question, does your card require a pin to unlock the certs?

@aafeijoo-suse
Copy link
Member

Not looking good on my side...

Nov 03 10:55:02 localhost systemd[1]: Listening on pcscd.socket.
Nov 03 10:55:02 localhost systemd[1]: Started pcscd.service.
Nov 03 10:55:02 localhost pcscd[191]: 00000000 auth.c:92:IsClientAuthorized() polkit_authority_get_sync failed: Error initializing authority: Could not connect: No such file or directory
Nov 03 10:55:02 localhost pcscd[191]: 00000008 winscard_svc.c:336:ContextThread() Rejected unauthorized PC/SC client
Nov 03 10:55:02 localhost pcscd[191]: 00005539 auth.c:92:IsClientAuthorized() polkit_authority_get_sync failed: Error initializing authority: Could not connect: No such file or directory
Nov 03 10:55:02 localhost pcscd[191]: 00000003 winscard_svc.c:336:ContextThread() Rejected unauthorized PC/SC client
Nov 03 10:55:02 localhost systemd[1]: Starting dracut-cmdline-ask.service...
Nov 03 10:55:02 localhost systemd[1]: Finished dracut-cmdline-ask.service.

This means pcscd requires polkit and dbus... both are a bad idea.

@innovara
Copy link
Contributor Author

innovara commented Nov 3, 2023

The current upstream rule is to follow only other upstreams, so remove all the comments and add only what the OpenSC packaging says: /usr/share/p11-kit/modules/opensc.module

Great. I suspected there would be an upstream package path but I missed the obvious, checking their code.

I got a smart card reader and a card with certs, so I'll test that this is working fine. One question, does your card require a pin to unlock the certs?

Yes, the slot I use requires a PIN, and when I tried with one that it doesn't, it didn't work. But be aware that you need one more change on dracut's side for it to work. I haven't sent anything yet because I need a bit of advice regarding pcscd

@innovara
Copy link
Contributor Author

innovara commented Nov 3, 2023

This means pcscd requires polkit and dbus... both are a bad idea.

You arrived to what it was going to be my 3rd change request but I need advice.

pcscd introduced --disable-polkit on 2.0.0 precisely to address this [1].

So the next and last change needed to make it all work is to change pcscd.service

- ExecStart=/usr/sbin/pcscd --foreground --auto-exit
+ ExecStart=/usr/sbin/pcscd --foreground --auto-exit --disable-polkit

But that change is obviously not going to be compatible with hosts using earlier versions of pcsc. However, dracut's pcsc module is broken anyway, so in some ways it doesn't really matter if we break it differently for pcsc < 2.0.0.

What do you think?

I tested all this on Fedora 39 that uses pcsc-2.0.0 and it works as expected. pcscd is triggered at the right time, you get asked your PIN and it unlocks the LUKS encrypted volume.

[1] https://github.com/LudovicRousseau/PCSC/releases/tag/2.0.0

@aafeijoo-suse
Copy link
Member

pcscd introduced --disable-polkit on 2.0.0 precisely to address this [1].

So the next and last change needed to make it all work is to change pcscd.service

- ExecStart=/usr/sbin/pcscd --foreground --auto-exit
+ ExecStart=/usr/sbin/pcscd --foreground --auto-exit --disable-polkit

IMO this is definitely the way to go, please update your commit or add another one with this change, so we can completely fix this module.

But that change is obviously not going to be compatible with hosts using earlier versions of pcsc. However, dracut's pcsc module is broken anyway, so in some ways it doesn't really matter if we break it differently for pcsc < 2.0.0.

What do you think?

I'm not sure if this module has ever worked... even with polkit disabled I found some issues in systemd which I need to analyze further.

@innovara
Copy link
Contributor Author

innovara commented Nov 3, 2023

I'm not sure if this module has ever worked... even with polkit disabled I found some issues in systemd which I need to analyze further.

You might be getting to another issue with systemd-cryptenroll. Currently, it enrols the certificate on the card. So you have to dump the token e.g. sudo cryptsetup token export --token-id 0 /dev/xxx > header.json, edit pkcs11-uri on header.json, and import it back with sudo cryptsetup token import --json-file header.json --token-replace --token-id 0 /dev/xxx.

You get the pkcs11-uri that you need using p11tool. First you run p11tool --login --list-all to get the list of tokens available and then p11tool --login --list-all pkcs11:model=...URI of the card. You'll have to find the key that goes with your certificate and copy the URL of the object type Private key (RSA-2048).

I think there is some work being done in systemd to address this issue, adding support for EC keys, adding PIN to the URI so you don't have to type it.

systemd/systemd#29692

@aafeijoo-suse
Copy link
Member

Thanks for your help, I found that problem already, but the proposed workaround led me to another error (Failed to find selected private key suitable for decryption on token), after replacing the certificate in pkcs11-uri with the proper private key in the luks2 header... This functionality is more broken than I initially thought :)

@innovara
Copy link
Contributor Author

innovara commented Nov 3, 2023

Yeah, I spent some time troubleshooting and I got that error a few times. Usually, there is something not right with the URI, it's the wrong object, or it's not a RSA 2048 key. It also happened to me when I tried to use slot 9e which is supposed to work without PIN. Another mistake was to reuse header.json between a few tests. In the end I always made sure that I deleted the LUKS password slot, 1 in my case but be careful, with sudo cryptsetup luksKillSlot /dev/xxx 1 as well as the token with sudo cryptsetup token remove --token-id 0 /dev/xxx. Then start again the enrol process.

One thing I did that helped me was to create a small LUKS partition and get that working with my card before adding dracut into the mix. Basically, unlocking it from the operating system with sudo /lib/systemd/systemd-cryptsetup attach luks-UUID.... /dev/xxxx - pkcs11-uri=auto. If you get that working then you know your token and systemd-cryptsetup can work together and move onto bootup.

@innovara
Copy link
Contributor Author

innovara commented Nov 4, 2023

One further thought is that, if you are using a pkcs11 token, you need the change introduced by this PR for it to work at bootup: #2540

@innovara
Copy link
Contributor Author

May I ask what are the next steps on a PR of this kind? Is it going to be merged on a future release? I'd love to see it on the next version of Fedora. Ironically, it's been backported to openSUSE!

Copy link
Member

@aafeijoo-suse aafeijoo-suse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to see it on the next version of Fedora. Ironically, it's been backported to openSUSE!

Why is that an irony? I guess you can explicitly request that: https://src.fedoraproject.org/rpms/dracut/pull-requests

@innovara
Copy link
Contributor Author

Why is that an irony?

in a way that is interesting, strange, or funny because of being very different from what you would expect

My expectation was that the fix would be applied to the upstream project first, and the downstream projects would receive it in due course at their own update cadence.

Of course, if the patches are good to go and other downstream projects can/want to use them before they are merged upstream, even better as they will reach at least a subset of the users of the project.

@innovara
Copy link
Contributor Author

I guess you can explicitly request that: https://src.fedoraproject.org/rpms/dracut/pull-requests

Thanks for the tip. I did that and the patches will be used in future releases.

Copy link

stale bot commented Apr 22, 2024

This issue is being marked as stale because it has not had any recent activity. It will be closed if no further activity occurs. If this is still an issue in the latest release of Dracut and you would like to keep it open please comment on this issue within the next 7 days. Thank you for your contributions.

@stale stale bot added the stale communication is stuck label Apr 22, 2024
On Fedora, and possibly others, this file loads opensc-pkcs11.so which you need to interact with the smart card to unlock a LUKS encrypted volume.
Needs pcsc >= 2.0.0

polkit is not included in dracut and without this option, pcscd simply fails
@stale stale bot removed the stale communication is stuck label Apr 22, 2024
@github-actions github-actions bot added the pcsc label Apr 22, 2024
@innovara
Copy link
Contributor Author

This is still an issue in the latest release of Dracut.

imguoguo pushed a commit to fedora-riscv/dracut that referenced this pull request May 30, 2024
pkcs11 and pcsc don't seem to have ever worked.

In the case of pkcs11, the following install line is incorrect (note the dot before *):

{"tls/$_arch/",tls/,"$_arch/",}"/cryptsetup/libcryptsetup-token-systemd-pkcs11.so.*"

And it should be:

{"tls/$_arch/",tls/,"$_arch/",}"/cryptsetup/libcryptsetup-token-systemd-pkcs11.so*"

I opened a PR and it was merged a while ago: dracutdevs/dracut#2540

In the case of pcsc there are two problems.

One, the installation file is missing /usr/share/p11-kit/modules/opensc.module and without that, you can't really do anything.

Two, dracut doesn't include polkit and pcsc is compiled with it enabled by default. The option --disable-polkit was added to pcscd in 2.0, precisely to address this issue. It needs to be added to pcscd.service in the module for it to work on initramfs.

I opened another PR which has been approved by 2 reviewers and merged into openSUSE: dracutdevs/dracut#2547

Signed-off-by: Manuel Fombuena <[email protected]>
imguoguo pushed a commit to fedora-riscv/dracut that referenced this pull request May 30, 2024
pkcs11 and pcsc don't seem to have ever worked.

In the case of pkcs11, the following install line is incorrect (note the dot before *):

{"tls/$_arch/",tls/,"$_arch/",}"/cryptsetup/libcryptsetup-token-systemd-pkcs11.so.*"

And it should be:

{"tls/$_arch/",tls/,"$_arch/",}"/cryptsetup/libcryptsetup-token-systemd-pkcs11.so*"

I opened a PR and it was merged a while ago: dracutdevs/dracut#2540

In the case of pcsc there are two problems.

One, the installation file is missing /usr/share/p11-kit/modules/opensc.module and without that, you can't really do anything.

Two, dracut doesn't include polkit and pcsc is compiled with it enabled by default. The option --disable-polkit was added to pcscd in 2.0, precisely to address this issue. It needs to be added to pcscd.service in the module for it to work on initramfs.

I opened another PR which has been approved by 2 reviewers and merged into openSUSE: dracutdevs/dracut#2547

Signed-off-by: Manuel Fombuena <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
modules Issue tracker for all modules pcsc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants