pcsc_scan (from pcsc-tools) output:
3B 7F 96 00 00 80 31 B8 65 B0 85 04 02 1B 12 00 F6 82 90 00
Finnish ID-card v5.0(?) (eID)
https://dvv.fi/en/fineid-specifications
The communication flow is as follows: mutt -> gpgme -> (gpgsm) -> gpg-agent -> gnupg-pkcs11-scd -> libcryptoki -> smartcard
- pkcs11-helper
- gnupg-pkcs11
- Version > 0.9.2 because of #17
~/.gnupg/gpg-agent.conf:
scdaemon-program /usr/bin/gnupg-pkcs11-scd
~/.gnupg/gnupg-pkcs11-scd.conf:
providers p1
provider-p1-library /usr/lib64/libcryptoki.so
muttrc:
set crypt_use_gpgme
set smime_default_key="12345678.0" <- check your ID with the commands described below in "Usage"
set nohonor_disposition
gpgsm --learn-card
Run gpgsm --list-keys and check the ID of your cert with key usage: digitalSignature keyEncipherment dataEncipherment.
You can test whether your card is identified by running gpg-agent --server gpg-connect-agent and issuing the SCD LEARN command.
Determine your private key ID with pkcs11-tool --module /usr/lib64/libcryptoki.so --list-objects --type privkey. It should look like this:
Private Key Object; RSA
label: todentamis- ja salausavain
ID: 45
Usage: decrypt, sign
Determine the IDs of your "todentamis- ja salausvarmenne" certificate and the intermediate CA "VRK Gov. CA for Citizen Certificates - G3" certificate with the following command:
pkcs11-tool --module /usr/lib64/libcryptoki.so --list-objects --type cert
Extract the "todentamis- ja salausvarmenne" and "VRK Gov. CA for Citizen Certificates - G3" certificates from the card into separate files with (repeat and save into different files):
pkcs11-tool --module /usr/lib64/libcryptoki.so --read-object --id KEY_ID --type cert --output-file cert.der
Convert them from DER to PEM (repeat for both certificates):
openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM
Create the following OpenSSL configuration (see Using the engine from the command line):
openssl_conf = openssl_init
[openssl_init]
engines = engine_section
[engine_section]
pkcs11 = pkcs11_section
[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/lib64/engines-1.1/pkcs11.so
MODULE_PATH = /usr/lib64/libcryptoki.so
init = 0
- You need to disable GPGME in Mutt, so you can use the old school
smime_*_commands cert.pemis the extracted "todentamis- ja salausvarmenne" certificateca.pemis the "VRK Gov. CA for Citizen Certificates - G3" intermediate CA certificate- The key ID is hardcoded and determined in the "Determine your private key ID" part
smime_default_keyandsmime_sign_asare just dummy values so Mutt doesn't prompt you for the key ID
Add the following to your muttrc:
unset crypt_use_gpgme
set smime_default_key="12345678.0"
set nohonor_disposition
set smime_decrypt_command="OPENSSL_CONF=/path/to/openssl.conf openssl smime -decrypt -engine pkcs11 -keyform engine -inform DER -in %f -inkey 45"
set smime_sign_as="87654321.0"
set smime_sign_command="OPENSSL_CONF=/path/to/openssl.conf openssl smime -sign -engine pkcs11 -keyform engine -signer /path/to/cert.pem -certfile /path/to/ca.pem -inkey 45 -in %f -outform DER"
Mutt will ask you for a passphrase, but as this comes from mpollux you can enter anything to the prompt.
If you have #1608 patch, you can get your SSH public key with pkcs15-tool --read-ssh-key ID where ID is the ID of your "todentamis- ja salausvarmenne" certificate. You also need to have the following in /etc/opensc.conf or otherwise pkcs15-tool will not work:
app default {
card_atr 3b:7f:96:00:00:80:31:b8:65:b0:85:04:02:1b:12:00:f6:82:90:00 {
driver = fineid;
}
}
Do note that the patch does not seem to work properly with FINEID v5, except for the pkcs15-tool part so leaving it to your opensc.conf is not recommended.
Other option to convert your certificate into SSH authorized_key is to run openssl x509 -in cert.pem -noout -pubkey | ssh-keygen -i -m PKCS8 -f /dev/stdin.
You need to have the following in your SSH client configuration (ssh_config):
Host ...
PKCS11Provider /usr/lib64/libcryptoki.so
Then just add the public key into your authorized_key and you can authenticate with your FINEID card.
mPollux stores "DigiSign WebSigner ROOT Certificate" into your ~/.pki/nssdb database. It uses a password, which you can find from ~/.digisign/Seed.txt.
See DigiSignApplication.bin:
nth paddr vaddr len size section type string
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
2856 0x0043b520 0x0043b520 19 20 .rodata ascii /.digisign/Seed.txt
52823 0x006d4041 0x006d4041 2288 2289 .rodata ascii #!/bin/bash\n\npwdfile=$1\nnsdCreate=$2\n\nif [ -f /usr/lib/libcryptoki.so ]; then\n cryptokiPath=/usr/lib/libcryptoki.so;\nelse\n cryptokiPath=/usr/lib64/libcryptoki.so;\nfi\n\nif [ "$nsdCreate" = "true" ]; then\n certutil -d sql:$HOME/.pki/nssdb -N -f $pwdfile\nfi\n\nif [ $? -gt 0 ]; then\n echo nssdb creation failed\n exit 1\nfi\n\nhostname=$(hostname)\nif [ -z "$hostname" ]; then\n echo hostname not defined\n exit 1\nfi\n\nrootname="DigiSign WebSigner ROOT Certificate for $hostname"\n\n#Wrong password exit status: \n# local nssd: 2\n# firefox and thunderbird: 3\n\n#add root certificate to nssd db sent by parameters\naddRootCertificate()\n{\n dbPath=$1\n isPwdFile=$2\n exitStatus=$3\n\n certCheck=$(certutil -d $dbPath -L | grep "$rootname")\n if [ -n "$certCheck" ]; then\n #remove old certificate, ignore if it doesn't exist\n certutil -d $dbPath -D -n "$rootname"\n fi\n\n if [ "$isPwdFile" = "true" ]; then\n certutil -d $dbPath -A -t "TC,Tw,Tw" -n "$rootname" -i /etc/xdg/Fujitsu/SSLCA.cer -f $pwdfile\n else\n certutil -d $dbPath -A -t "TC,Tw,Tw" -n "$rootname" -i /etc/xdg/Fujitsu/SSLCA.cer\n fi\n if [ $? -gt 0 ]; then\n #if certificate inset failed for some reason, certutil added incorrect data to db. Clean incorrect data from db.\n certutil -d $dbPath -D -n "$rootname"\n exit $exitStatus\n fi\n #update pkcs11.txt\n isInFile=$(cat $dbPath/pkcs11.txt | grep -c "DigiSign PKCS#11 Module")\n\n if [ $isInFile -eq 0 ]; then\n echo "library=$cryptokiPath" >> $dbPath/pkcs11.txt\n\t echo "name=DigiSign PKCS#11 Module" >> $dbPath/pkcs11.txt\n fi\n}\n\naddRootCertificate $HOME/.pki/nssdb true 2\n\nif [ -d ~/snap/firefox ]; then\necho snap version\n for certDB in $(find ~/snap/firefox/common/ -name "cert9.db")\n do\n certDir=$(dirname ${certDB});\n\t addRootCertificate $certDir false 3\n done\nelse\n for certDB in $(find ~/.mozilla* ~/.thunderbird -name "cert9.db")\n do\n certDir=$(dirname ${certDB});\n\t addRootCertificate $certDir false 3\n done\n #we need also check cet8.db for old version of Firefox or thunderbird. More related to Ubuntu 32 version\n for certDB in $(find ~/.mozilla* ~/.thunderbird -name "cert8.db")\n do\n certDir=$(dirname ${certDB});\n\t addRootCertificate $certDir false 3\n done\nfi\n\nexit 0\n
Atostek ID is the new software that is going to replace mPollux. All these notes are about the Debian package.
https://files.fineid.fi/download/atostek/4.4.1.0/linux/AtostekID_DEB_4.4.1.0.deb
6fec3d89bf2ff95a2f12acd2d28563b9a4ce416d82de52e882401c4bce4ca647 AtostekID_DEB_4.4.1.0.deb
A mysterious private key is embedded within the binary:
nth paddr vaddr len size section type string
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
2197 0x005735a1 0x005735a1 3500 3501 .rodata ascii -----BEGIN ENCRYPTED PRIVATE KEY-----\r\n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\r\n-----END ENCRYPTED PRIVATE KEY-----\r\n
Couldn't find any code referencing it and apparently the installCA function does generate it's own keys.
You can find a reference string:
nth paddr vaddr len size section type string
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
471 0x0056521c 0x0056521c 27 28 .rodata ascii Entering installCA function
From there you can find the function:
address noret size nbbs edges cc cost min bound range max bound calls locals args xref frame name
================== ===== ===== ===== ===== ===== ==== ================== ===== ================== ===== ====== ==== ==== ===== ====
0x000000000013c180 0 7025 256 418 164 2394 0x000000000013c180 7279 0x000000000013ddef 288 31 1 1 520 fcn.0013c180
I dislike the idea of having random private keys stored on my computer and not knowing how to unlock them.
When you run the binary with the -installCA parameter, it creates this AID-ERASMARTCARD-EHOITO-FI-CA CA certificate for you into ~/.local/share/Atostek Oy/Atostek ID/ directory. The password for the PKCS #12 file is DyCpu4fB4y4WdsnCG6k3. The password is the same between different machines (e.g. not using any instance specific attributes to generate a unique one). You can breakpoint PKCS12_create to catch it.
You can see the password loaded into the r12 register before calling the function at 0x0013e430:
0x0013ca7a 4c8b6590 mov r12, qword [rbp - 0x70]
The -installSCSCA parameter installs another cert (AID_SCSCA) and the password for that is Le3svzKWE2OD4cgWzXan.