Hej!
Försöker få vår proof-of-concept att fungera med OpenPGP-kort (sedan tidigare funkar det med YubiKey och NitroKey HSM, men inte ännu med OpenPGP-kort).
Några länkar om bakgrunden finns längst ner i mejlet.
Allt som används nedan är fri programvara, de olika kommandona finns som Debian-paket till exempel.
Det jag vill kunna göra är följande tre saker:
(1) Skapa nyckelpar på smartkortet
(2) Skapa en motsvarande CSR-fil (som sen kan ges till utfärdaren som då kan skapa ett motsvarande personligt certifikat)
(3) Använda det personliga certifikatet för att identifiera sig mot en test-webbsida
Försöker få det att fungera med ett OpenPGP-kort av den här typen: https://www.cryptoshop.com/products/smartcards/proprietary-solution-cards/op...
Kommandon som kan användas för att visa info om smartkort (oavsett om det är ett OpenPGP-kort eller en YubiKey eller NitroKey eller liknande):
gpg --card-status
pkcs11-tool --list-slots
p11tool --list-tokens
Kommandot "p11tool --list-tokens" visar bland annat en "URL" för varje token, som kan användas som input till vissa andra kommandon för att säga vilken token man vill använda.
Man kan även köra det här för att visa bara just token url och inget annat:
p11tool --list-token-urls
Om man har ett cert (skapat med vår utfärdar-programvara) kan man använda det för att identifiera sig mot test-sidan https://eid-test-2.eliasrudberg.se/ med curl såhär:
curl --cert eid_200001012384.crt.pem --key $url https://eid-test-2.eliasrudberg.se/ Enter PKCS#11 token PIN for SmartCard-HSM (UserPIN): Hej 200001012384! Välkommen till Test-sajten :-)
(Alltså ovanstående "Välkommen till Test-sajten" är hur det ser ut om det fungerar, just nu kan jag få det att fungera med Nitrokey HSM men inte med OpenPGP-kortet, mer om det här nedanför)
Följande kan hjälpa för att undvika konflikter när olika programvaror försöker dra i smartkortet samtidigt:
echo disable-ccid >> ~/.gnupg/scdaemon.conf
Se https://support.yubico.com/hc/en-us/articles/4819584884124-Resolving-GPG-s-C...
Ett sätt att skapa nyckelpar på kortet är det här:
gpgsm --generate-key > my-openpgp-card.csr
(men kanske inte bästa sättet)
Ett annat sätt är det här:
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so --login --login-type so --keypairgen --key-type rsa:2048 --id 3 --so-pin 12345678
Valet av "id" spelar roll, alltså "--id 3" ovan. Det går att köra med id 1 eller 2 också, men då blir det problem senare så jag tror att 3 är bäst.
Outputen från kommandot ovan ser ut såhär:
Using slot 0 with a present token (0x0) Key pair generated: Private Key Object; RSA label: Private Key ID: 03 Usage: decrypt, sign Access: none Public Key Object; RSA 16384 bits label: Private Key ID: 03 Usage: encrypt, verify Access: none
Om man kör "gpg --card-status" i det läget kan man se att en "Authentication key" har skapats på OpenPGP-kortet.
Sen kan man skapa CSR såhär:
openssl req -new -engine pkcs11 -subj "/C=GB/CN=foo" -key id_3 -keyform engine -out openpgpcard_id3.csr.pem
Den CSR-filen kan ges till utfärdaren, praktiskt nog i detta test är utfärdaren jag själv :-)
(Den som vill testa kan själv vara utfärdare om man vill, koden finns här https://codeberg.org/DFRI-eID/dfri-eid)
Utfärdaren skapar cert och sen kan man försöka använda sitt cert.
curl --cert eid_200001012394.crt.pem --key $url https://eid-test-2.eliasrudberg.se/
(där $url ovan är en url man fått fram med t.ex. "p11tool --list-token-urls")
Då blir det dock problem:
curl --cert eid_200001012394.crt.pem --key $url https://eid-test-2.eliasrudberg.se/ Enter PKCS#11 token PIN for OpenPGP card (User PIN): curl: (35) error:8207A070:PKCS#11 module:pkcs11_private_encrypt:Mechanism invalid
Felmeddelandet säger "Mechanism invalid" alltså.
Genom att lägga till OPENSC_DEBUG=9 kan man få en massa debug-loggning:
OPENSC_DEBUG=9 PKCS11SPY=/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so curl -vvvv --cert eid_200001012394.crt.pem --key $url https://eid-test-2.eliasrudberg.se/
Då ser man bland annat följande som verkar intressant:
P:16041; T:0x140368933964096 19:47:35.351 [opensc-pkcs11] framework-pkcs15.c:3689:pkcs15_prkey_get_attribute: pkcs15_prkey_get_attribute() called P:16041; T:0x140368933964096 19:47:35.351 [opensc-pkcs11] framework-pkcs15.c:3689:pkcs15_prkey_get_attribute: pkcs15_prkey_get_attribute() called P:16041; T:0x140368933964096 19:47:35.351 [opensc-pkcs11] mechanism.c:251:sc_pkcs11_sign_init: called P:16041; T:0x140368933964096 19:47:35.352 [opensc-pkcs11] mechanism.c:256:sc_pkcs11_sign_init: mechanism 0xD, key-type 0x0 P:16041; T:0x140368933964096 19:47:35.352 [opensc-pkcs11] mechanism.c:260:sc_pkcs11_sign_init: returning with: 112 P:16041; T:0x140368933964096 19:47:35.352 [opensc-pkcs11] pkcs11-object.c:679:C_SignInit: C_SignInit() = CKR_MECHANISM_INVALID P:16041; T:0x140368933964096 19:47:35.352 [opensc-pkcs11] framework-pkcs15.c:3689:pkcs15_prkey_get_attribute: pkcs15_prkey_get_attribute() called P:16041; T:0x140368933964096 19:47:35.352 [opensc-pkcs11] framework-pkcs15.c:3689:pkcs15_prkey_get_attribute: pkcs15_prkey_get_attribute() called P:16041; T:0x140368933964096 19:47:35.352 [opensc-pkcs11] mechanism.c:251:sc_pkcs11_sign_init: called P:16041; T:0x140368933964096 19:47:35.352 [opensc-pkcs11] mechanism.c:256:sc_pkcs11_sign_init: mechanism 0x3, key-type 0x0 P:16041; T:0x140368933964096 19:47:35.353 [opensc-pkcs11] mechanism.c:260:sc_pkcs11_sign_init: returning with: 112 P:16041; T:0x140368933964096 19:47:35.353 [opensc-pkcs11] pkcs11-object.c:679:C_SignInit: C_SignInit() = CKR_MECHANISM_INVALID
Alltså, den försöker använda "mechanism 0xD" och sen "mechanism 0x3" och sen ger den upp.
Det går att lista vilka mechanisms som ett smartkort har stöd för såhär:
p11tool --list-mechanisms $url [0x0220] CKM_SHA_1 digest [0x0255] CKM_SHA224 digest [0x0250] CKM_SHA256 digest [0x0260] CKM_SHA384 digest [0x0270] CKM_SHA512 digest [0x0210] CKM_MD5 digest [0x0240] CKM_RIPEMD160 digest [0x1210] CKM_GOSTR3411 digest [0x0001] CKM_RSA_PKCS keysize range (2048, 2048) hw decrypt sign verify [0x0006] CKM_SHA1_RSA_PKCS keysize range (2048, 2048) sign verify [0x0046] CKM_SHA224_RSA_PKCS keysize range (2048, 2048) sign verify [0x0040] CKM_SHA256_RSA_PKCS keysize range (2048, 2048) sign verify [0x0041] CKM_SHA384_RSA_PKCS keysize range (2048, 2048) sign verify [0x0042] CKM_SHA512_RSA_PKCS keysize range (2048, 2048) sign verify [0x0005] CKM_MD5_RSA_PKCS keysize range (2048, 2048) sign verify [0x0008] CKM_RIPEMD160_RSA_PKCS keysize range (2048, 2048) sign verify [0x0000] CKM_RSA_PKCS_KEY_PAIR_GEN keysize range (2048, 2048) generate_key_pair
Kollar samma sak "p11tool --list-mechanisms" for Nitrokey HSM:
p11tool --list-mechanisms $url2 [0x0220] CKM_SHA_1 digest [0x0255] CKM_SHA224 digest [0x0250] CKM_SHA256 digest [0x0260] CKM_SHA384 digest [0x0270] CKM_SHA512 digest [0x0210] CKM_MD5 digest [0x0240] CKM_RIPEMD160 digest [0x1210] CKM_GOSTR3411 digest [0x1041] CKM_ECDSA keysize range (192, 521) hw sign ec_f_p ec_namedcurve ec_uncompress [0x1042] CKM_ECDSA_SHA1 keysize range (192, 521) hw sign ec_f_p ec_namedcurve ec_uncompress [0x1051] CKM_ECDH1_COFACTOR_DERIVE keysize range (192, 521) hw derive ec_f_p ec_namedcurve ec_uncompress [0x1050] CKM_ECDH1_DERIVE keysize range (192, 521) hw derive ec_f_p ec_namedcurve ec_uncompress [0x1040] CKM_ECDSA_KEY_PAIR_GEN keysize range (192, 521) hw generate_key_pair ec_f_p ec_namedcurve ec_uncompress [0x0003] CKM_RSA_X_509 keysize range (1024, 4096) hw decrypt sign verify [0x0001] CKM_RSA_PKCS keysize range (1024, 4096) hw decrypt sign verify [0x0006] CKM_SHA1_RSA_PKCS keysize range (1024, 4096) sign verify [0x0046] CKM_SHA224_RSA_PKCS keysize range (1024, 4096) sign verify [0x0040] CKM_SHA256_RSA_PKCS keysize range (1024, 4096) sign verify [0x0041] CKM_SHA384_RSA_PKCS keysize range (1024, 4096) sign verify [0x0042] CKM_SHA512_RSA_PKCS keysize range (1024, 4096) sign verify [0x0005] CKM_MD5_RSA_PKCS keysize range (1024, 4096) sign verify [0x0008] CKM_RIPEMD160_RSA_PKCS keysize range (1024, 4096) sign verify [0x000d] CKM_RSA_PKCS_PSS keysize range (1024, 4096) hw sign verify [0x000e] CKM_SHA1_RSA_PKCS_PSS keysize range (1024, 4096) sign verify [0x0047] CKM_SHA224_RSA_PKCS_PSS keysize range (1024, 4096) sign verify [0x0043] CKM_SHA256_RSA_PKCS_PSS keysize range (1024, 4096) sign verify [0x0044] CKM_SHA384_RSA_PKCS_PSS keysize range (1024, 4096) sign verify [0x0045] CKM_SHA512_RSA_PKCS_PSS keysize range (1024, 4096) sign verify [0x0000] CKM_RSA_PKCS_KEY_PAIR_GEN keysize range (1024, 4096) generate_key_pair
Då ser man att för Nitrokey HSM finns både "mechanism 0xD" och sen "mechanism 0x3"
[0x000d] CKM_RSA_PKCS_PSS keysize range (1024, 4096) hw sign verify
[0x0003] CKM_RSA_X_509 keysize range (1024, 4096) hw decrypt sign verify
Men för OpenPGP-kortet saknas de två.
Alltså:
mechanism 0xD --> [0x000d] CKM_RSA_PKCS_PSS keysize range (1024, 4096) hw sign verify --> finns för nitrokey HSM --> finns INTE för openpgp-kortet
mechanism 0x3 --> [0x0003] CKM_RSA_X_509 keysize range (1024, 4096) hw decrypt sign verify --> finns för nitrokey HSM --> finns INTE för openpgp-kortet
Nar det gäller "mechanism 0xD" CKM_RSA_PKCS_PSS finns det liknande i alla fall: Det finns en som heter CKM_RSA_PKCS på openpgp-kortet:
[0x0001] CKM_RSA_PKCS keysize range (2048, 2048) hw decrypt sign verify
Funderingar:
Kan det gå att göra någon inställning (eller annan version av curl eller SSL-bibliotek eller så) så att CKM_RSA_PKCS används istället för CKM_RSA_PKCS_PSS (alltså att välja att använda det som stöds av OpenPGP-kortet)?
Kan det vara så att någon annan variant av OpenPGP-kort (nyare version kanske) skulle kunna ha stöd för någon av de "mechanisms" som verkar behövas?
Tacksam för alla tips och idéer om hur man kommer vidare!
/ Elias
PS
Länkar till tidigare mejl om liknande saker:
https://mailman.dfri.se/mailman3/hyperkitty/list/eleg-projekt@lists.dfri.se/...
https://mailman.dfri.se/mailman3/hyperkitty/list/eleg-projekt@lists.dfri.se/...
https://mailman.dfri.se/mailman3/hyperkitty/list/eleg-projekt@lists.dfri.se/...
https://mailman.dfri.se/mailman3/hyperkitty/list/eleg-projekt@lists.dfri.se/...