This post has been written as a memory dump from my experiments with the SSH service and the PKI card. I hope you find it useful.
I assume that you have a PKI card and reader. You can have a build-in reader like me (Broadcom Corp 5880) or an external one like Omnikey HO3121 USB2 (I also have it). In addition, you need software that will make your PKI reader and card visible on your system (installation of it is not part of this post).
My native system on which I work every day is Linux Mint ( yeah, life is much easier !!! ), but I will also write a part for Windows.
Depends on the software you use with the card reader on Windows, you must follow the instruction to it to access the card reader and card. I use Atos CardOs API and all required information is available when I click small Chip logo in the icon's try bar..
On Linux, I use opensc tools to talk to reader and card.
Let's start by checking if my card reader is recognized by the software:
$ opensc-tool --list-readers
# Detected readers (pcsc)
Nr. Card Features Name
0 Yes Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
I have a Broadcom Corp 5880 PKI card reader on channel 0. Now let's list all the certificates on my card:
$ pkcs15-tool --dump
Using reader with a card: Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
PKCS#15 Card [PKCS#15]:
Version : 0
Serial number :
Manufacturer ID: www.atos.net/cardos
Flags : Login required, PRN generation
PIN [PIN]
Object Flags : xxxxxxxxxxxx
Auth ID : 02
ID : 01
Flags : xxxxxxxxxxxx
Length : xxxxxxxxxxxx
Pad char : 0x00
Reference : xxxxxx
Type : UTF-8
AuthKey [Admin Key]
PIN [Extra PIN #0]
Private RSA Key
Private RSA Key
Private RSA Key
.
.
.
< more and more and more >
Communication with the PKI card also works.
If at any time after verification that you have access the the PKI card, you will receive information that the card ID is unavailable / present, but the card is in the reader, do what I do, reseat the card. It always works (for me).
Now it's time to focus on what we need - Public RSA keys, so let's list only them:
$ pkcs15-tool --list-public-keys
Using reader with a card: Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
Public RSA Key [irek AUT 11]
Object Flags : xxxxxxxxxxxxx
Usage : xxxxxxxxxxxxx
Access Flags : xxxxxxxxxxxxx
ModLength : xxx
Key ref : xxxxxxxxxxxxx
Native : xxxxxxxxxxxxx
Path : xxxxxxxxxxxxx
ID : d62edf638a8e66bb2914209cf96483a6ac55dda9
Public RSA Key [irek ENC 21]
Object Flags : xxxxxxxxxxxxx
Usage : xxxxxxxxxxxxx
Access Flags : xxxxxxxxxxxxx
ModLength : xxx
Key ref : xxxxxxxxxxxxx
Native : xxxxxxxxxxxxx
Path : xxxxxxxxxxxxx
ID : 2a760dddf9890fa6144f331b992a47508b3466bc
Public RSA Key [irek ENC 11]
Object Flags : xxxxxxxxxxxxx
Usage : xxxxxxxxxxxxx
Access Flags : xxxxxxxxxxxxx
ModLength : xxx
Key ref : xxxxxxxxxxxxx
Native : xxxxxxxxxxxxx
Path : xxxxxxxxxxxxx
ID : f58b9040e9f6f95ad088d3d87e50ca36c5519475
I have 3 public RSA keys and I can use any, so I will use 1st one designated for Authentication. Its ID is d62edf638a8e66bb2914209cf96483a6ac55dda9 and we will need this information in next task.
There are many ways to get a public SSH key from an x509 key, but I'll show you two of them:
We need the key ID from the previous command (ID:d62edf638a8e66bb2914209cf96483a6ac55dda9) to get the key we need. We are running:
$ pkcs15-tool -r d62edf638a8e66bb2914209cf96483a6ac55dda9 2> /dev/null|openssl x509 -pubkey -noout|ssh-keygen -i -f /dev/fd/0 -m PKCS8
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC……………………………………………………………………………………………………………………………………………/L+ZZnl
Knowing that the key we are looking for is the 1st key on that list, we are running:
$ ssh-keygen -D /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC………………………………………………………………………………………………………………………………….../L+ZZnl
ssh-rsa 2nd key /bLb
ssh-rsa 3rd key dU9r
Download putty-cac and set “PKCS Cert” to point to the CardOs library cardos11_64.dll (C:\Windows\System32\cardos11_64.dll) or any other provider’s library. The “Copy To Clipboard” button copies the public key to the clipboard, and this part have to be added to “authorized_keys” file on the Linux server.
The generated public ssh key must be added to “.ssh/authorized_keys” on the remote system under the account where we want to login using PKI card.
$ ssh -I /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so 192.168.56.130
Enter PIN for 'PIN (PKCS#15 Card + O':
Last login: Wed May 22 17:49:21 2019 from 192.168.56.1
To complicate things even little bit more, we can add an option that requires a password and PKI card for authentication. To do this, edit "/etc/ssh/sshd_config" and add/setup:
AuthenticationMethods "publickey,keyboard-interactive"
ChallengeResponseAuthentication no
Now we need to restart/reload the sshd service and see if it works.