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

A Slovakian eID card driver? #208

Closed
martinvarga opened this issue Jan 17, 2014 · 23 comments
Closed

A Slovakian eID card driver? #208

martinvarga opened this issue Jan 17, 2014 · 23 comments

Comments

@martinvarga
Copy link

I am just started writing a driver for Slovakian eID for fun, despite there is a promise from authorities to provide some Linux support in future.

Because I am a naive newbie in opensc and smart cards and till now I have no technical specification for this card, I appreciate any information and help from community.

For now, the plan is to find suitable implementation of function from existing drivers and integrating them into the driver.

If you are interested you are welcome to join.

For now, there is only detection of card and only default iso 7816 functions.

/tools/opensc-tool --reader 0 --atr
3b:df:18:00:81:31:fe:58:00:31:b9:64:05:0e:01:00:73:b4:01:d3:00:00:00:22

varga@ntb-varga:src$ ./tools/opensc-tool --reader 0 --name
Slovakian eID

Martin

@martinpaljak
Copy link
Member

  1. Find out if you have some kind of documentation available. Pointers to specs are helpful.
  2. If you can, do a USB snoop of Windows running in a virtual machine on Linux, so you can get the APDU-s of your card
  3. Good luck :)

@frankmorgner
Copy link
Member

Please re-open the issue if you stumble upon problems for your implementation.

@andrewshadura
Copy link

The newly published closed-source Linux Slovak eID client contains 8 XML files which may be of some interest. They all begin with

<iso:CardInfo xmlns:iso="urn:iso:std:iso-iec:24727:tech:schema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:iso:std:iso-iec:24727:tech:schema CardInfo.xsd">

and describe APDUs like this:

      <iso:CardCall>
        <!-- 3. Check eSign.PIN state -->
        <iso:CommandAPDU>00200081</iso:CommandAPDU>
        <iso:ResponseAPDU>
          <iso:Trailer>6A88</iso:Trailer>
        </iso:ResponseAPDU>
        <iso:ResponseAPDU>
          <iso:Trailer>6984</iso:Trailer>
        </iso:ResponseAPDU>
      </iso:CardCall>

@frankmorgner
Copy link
Member

Sounds like it's a software according to ISO 24727, similar to https://github.com/ecsec/open-ecard. The CardInfo files indeed say something about the card, but unfortunately don't tell the whole story.

But I could have a look at it, maybe the card is similar to the German ID card...

@andrewshadura
Copy link

Yes, I found that already… Yet that Java application doesn't work here for a reason.

I don't know if it's a good idea to post these files here (as the license is not known), so probably I just give you a link to the download page: https://eidas.minv.sk/TCTokenService/download/. It is in Slovak, but it's pretty easy to understand what's where (Stiahnuť inštalátor next to Debian 7.0 should be a link to the tarball with .deb inside).

@frankmorgner
Copy link
Member

The XML files look indeed very similar to the CardInfo files of the German ID card.

You may want to have a look at my driver for the nPA https://frankmorgner.github.io/vsmartcard/npa/README.html, which integrates int OpenSC and implements all the mechanisms your card uses, too. You can use npa-tool to perform PACE/TA/CA.

Please note that by design EAC (eID) will not be available via pkcs#11/minidriver. But you should be able, however, to use eSign (if your card is initialized).

@andrewshadura
Copy link

Oh, I'm looking into building instructions… so convoluted :)

@danielkucera
Copy link

Why not to use vendor supplied library? https://blog.danman.eu/ssh-autentifikacia-s-eid-obcianskym-preukazom-pod-linuxom/

@andrewshadura
Copy link

Because it's not free software and doesn't work reliably?

@danielkucera
Copy link

OK, excuse my stupid question sir

@pali
Copy link

pali commented Jan 5, 2017

Study of the eID Model in Slovakia:
http://www.sdisk.eu/projekty/2014/study-of-the-eid-model-in-slovakia/

The solution used for the Slovak eID card is derived from the German eID card system and based on EAC technology, according to BSI TR-03110. Rather than using an X.509 certificate, the verification of an electronic identity stored in the eID card based on reading the identity data via an EAC channel is used for electronic authentication and identification.

@frankmorgner
Copy link
Member

Then my comment from above holds. According to your citation, the Slovakian card has a QES functionality that is compatible with PKCS#11 and Minidriver/CSP. It's the same for the German ID card. The latter is fully integrated in my fork of OpenSC (pull request).

Since I implemented all of BSI TR-03110, I suppose the Slovakian card could be used with minor adjustments (for example adding an ATR for recognizing the card). You could verify the compatibility in my fork using the npa-tool, which ignores the ATR, but allows all cryptographic operations (i.e. EAC).

@andrewshadura
Copy link

@frankmorgner, 5 years later I think I’m motivated to have a look at this again, but I’m unsure where to start. npa-tool, of course, doesn’t recognise the card as is.

@frankmorgner
Copy link
Member

npa-tool is not tied to a specific card driver and may work with your card as well. We recently integrated the Polish ID card, which also uses eID (PACE) for communicating with the card. You may want to look at card-edo.c for a starting point.

@andrewshadura
Copy link

I tried forcing the npa driver (by also modifying the matching function) and managed to get it a bit further. I then thought of modifying the unlock routine to use the different card app id my card has just to see whether it can talk to it, but also found the esign_chat constant with no explanation of what it means or how it is used. Having a glance at the PACE API didn’t give me any hints.

@frankmorgner, do you use any chat platforms, IRC etc? It would be great to talk about this in a slightly more real-time fashion if you’re not strictly opposed to the idea 😃

@andrewshadura
Copy link

A bit more info. If I "force" npa-tool to use the npa driver, I goes through as far as this:

13:54:11.498 [npa-tool] card.c:523:sc_unlock: called
13:54:11.498 [npa-tool] reader-pcsc.c:736:pcsc_unlock: called
13:54:11.507 [npa-tool] iso7816.c:128:iso7816_check_sw: End of file/record reached before reading Le bytes
[ERROR] (eac_asn1.c:685 ) Unknown Identifier (UNDEF) for 1.0.24727.3.0.9
13:54:11.508 [npa-tool] sm-eac.c:1144:perform_pace: Could not parse EF.CardAccess.

I have also snooped the official driver’s comms (APDUs and SWs), I can share them privately if you’re interested.

@frankmorgner
Copy link
Member

I'd like to avoid IRC and the like. Send me the log to my email frankmorgner at gmail.com, and I'll take a look if i have some minutes

@andrewshadura
Copy link

Ack, sent; thanks for your help!

@frankmorgner
Copy link
Member

The error above is actually an informative message and doesn't lead to an abortion. 1.0.24727.3.0.9 is defined in ISO/IEC 24727-3, clause A.9. Although the document doesn't go into detail, the workflow chart seems to indicate that the terminal is doing a standard PIN verification (as opposed to, for example, PACE). However, authentication with EAC as implemented in npa-tool strictly requires PACE. That's why npa-tool stops here.

The good news is, that the log you've sent me indicates that the card doesn't use any secure messaging what so ever. The only interesting things in the pcscd log are

  • PIN verification is done in clear text with a VERIFY (if it's a contactless card, this may be a problem)
  • The middleware selects files named something like APPCONTAINER01 and authenticates to the card. Therefor, it fetches a 32 bytes nonce from the card (GET CHALLENGE) and sends back a dynamic authentication data (tag 7C) with some 8 byte value (nonce?) and another 32 bytes value with a EXTERNAL AUTHENTICATE.
  • In the log, there is no standard command that actually signs some data, e.g. a PERFORM SECURITY OPERATION.

The bad news without further research or specification we're stuck here. To proceed, you need to find out the following:

  • What are the commands for signing? (get a pcsc log of what the official software is doing, when signing a document)
  • How does the authentication protocol actually work and when is it needed?
  • If the official software is working offline, then the credential for authenticating to the card is contained in the binary. You may need to extract it from there to use it in OpenSC.

I'm think without help of someone familiar with your card we will not be able to integrate your card into OpenSC.

@scrool
Copy link

scrool commented Jul 13, 2021

A year later I have found this issue while trying to figure out if I could use open source software to interact with my new Slovak ID card. I'll start with a comment in this issue but if you prefer I could open new one.

Firstly Slovakia used to issue ID cards with "Smart Card Atos CardOS V5.0 QES EAC V1.0 version V1.0" [1] which certification ended on June 26. My card was issued after this date and I haven't found exact identification of a chip and applications there.

My card has ATT

Output of pscs_scan:

$ pcsc_scan
Using reader plug'n play mechanism
Scanning present readers...
0: Microchip SEC1110 [CCID Interface] (E8EFE018) 00 00

Tue Jul 13 21:44:12 2021
 Reader 0: Microchip SEC1110 [CCID Interface] (E8EFE018) 00 00
  Event number: 2
  Card state: Card inserted,
  ATR: 3B D2 18 00 81 31 FE 58 C9 04 11

ATR: 3B D2 18 00 81 31 FE 58 C9 04 11
+ TS = 3B --> Direct Convention
+ T0 = D2, Y(1): 1101, K: 2 (historical bytes)
  TA(1) = 18 --> Fi=372, Di=12, 31 cycles/ETU
    129032 bits/s at 4 MHz, fMax for Fi = 5 MHz => 161290 bits/s
  TC(1) = 00 --> Extra guard time: 0
  TD(1) = 81 --> Y(i+1) = 1000, Protocol T = 1
-----
  TD(2) = 31 --> Y(i+1) = 0011, Protocol T = 1
-----
  TA(3) = FE --> IFSC: 254
  TB(3) = 58 --> Block Waiting Integer: 5 - Character Waiting Integer: 8
+ Historical bytes: C9 04
  Category indicator byte: C9 (proprietary format)
+ TCK = 11 (correct checksum)

which unfortunately ends up with "Your card is not present in the database."

By trial and error I have found out that driver is still cardos and emulation cardos produced the least errors and queried the card similarly to the original application (called eidklient). My configuration [2] for reference.


Official linux application uses pcssd so I have enabled debug mode and captured communication between the device and the app. I guess vendor uses similar approach as I saw with Polish (#1831 and #1992) and probably German version.

I'm pretty new in smart cards but I'm able to read C code. I'm trying to compare pkcs15-tool --dump --short -vvvvv with original app to find differences.

  1. eidklient starts with:
APDU: 00 A4 00 0C 
SW: 90 00 

which is repeated also somewhat later. I guess this might be a ping or noop?

  1. Both probe data field length with get data. For some reason they do it differently.

a) eidklient:

APDU: 00 CA 01 82 00 
SW: C9 04 90 00 

b) pkcs15-tool (

/* probe DATA FIELD LENGTH with GET DATA */
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x8D);
) sends (and gets):

APDU: 00 CA 01 8D 02 
SW: 01 B5 90 00 

which later in logs means:

card-cardos.c:322:cardos_init: data_field_length:437 card->reader->max_send_size:65536 card->reader->max_recv_size:65536 SC_CARD_CAP_APDU_EXT
card.c:382:sc_connect_card: card info name:'Atos CardOS', type:1010, flags:0x0, max_send/recv_size:431/435

I've tried to change that constant except of the last byte (0x02) and I got:

APDU: 00 CA 01 82 02
SW: C9 04 90 00

card-cardos.c:322:cardos_init: data_field_length:51460 card->reader->max_send_size:65536 card->reader->max_recv_size:65536 SC_CARD_CAP_APDU_EXT
card.c:382:sc_connect_card: card info name:'Atos CardOS', type:1010, flags:0x0, max_send/recv_size:51454/51458
  1. eidklient sends same data as in 1) - probably ping/noop

  2. Next message is sc_enum_apps:

    OpenSC/src/libopensc/dir.c

    Lines 176 to 177 in 2f94a6b

    sc_format_path("3F002F00", &path);
    r = sc_select_file(card, &path, &ef_dir);
    . This call and first response is exactly the same with eidklient

  3. eidklient sends same data as in 1) - probably ping/noop

  4. Then:

a) pkcs15-tool seems to process data, ends up in

if (ef_structure == SC_FILE_EF_TRANSPARENT) {
parses initial binary data
r = sc_read_binary(card, 0, buf, file_size, 0);
and sends:

apdu.c:367:sc_single_transmit: CLA:0, INS:B0, P1:0, P2:0, data(0) (nil)

Outgoing APDU (7 bytes):
APDU: 00 B0 00 00 00 01 B3 

which seems to return some bunch of data. I'm not sure how identifiable they are but they contain more or less these ASCII strings:

ESignforAQES
QESforAQES
NationalIdentificationCard,Slovakia
CIAforAQES
CIAforESIGN

b) eidklient seems to send completely different data:

APDU: 00 A4 00 00 02 2F 00 00 
  1. pkcs15-tool then loops over dir records
    r = parse_dir_record(card, &p, &bufsize, -1);
    :
dir.c:75:parse_dir_record: called
dir.c:158:parse_dir_record: returning with: 0 (Success)
dir.c:75:parse_dir_record: called
dir.c:158:parse_dir_record: returning with: 0 (Success)
dir.c:75:parse_dir_record: called
dir.c:158:parse_dir_record: returning with: 0 (Success)
dir.c:75:parse_dir_record: called
dir.c:158:parse_dir_record: returning with: 0 (Success)
dir.c:75:parse_dir_record: called
dir.c:158:parse_dir_record: returning with: 0 (Success)
dir.c:75:parse_dir_record: called
dir.c:89:parse_dir_record: returning with: -1403 (Premature end of ASN.1 stream)

Which apparently ends up with an error.

  1. I haven't looked up what pkcs15-tool is trying to do, so only bunch of code here:
pkcs15.c:993:sc_pkcs15_bind_internal: bind to application('(null)',aid:'A000000851000014')
pkcs15.c:1013:sc_pkcs15_bind_internal: application path '3f000102'
card.c:844:sc_select_file: called; type=2, path=3f000102
...
[pkcs15-tool] apdu.c:367:sc_single_transmit: CLA:0, INS:A4, P1:8, P2:C, data(2) 0x7ffd600199e2
...
APDU: 00 A4 08 0C 02 01 02 
SW: 90 00 

Which ends up with success.

Then:

pkcs15.c:1039:sc_pkcs15_bind_internal: absolute path to EF(ODF) 3f0001025031
card.c:844:sc_select_file: called; type=2, path=3f0001025031
...
apdu.c:367:sc_single_transmit: CLA:0, INS:A4, P1:8, P2:0, data(4) 0x7ffd600199e2

which fails:

pkcs15.c:1050:sc_pkcs15_bind_internal: EF(ODF) not found in '3f0001025031'
pkcs15.c:1205:sc_pkcs15_bind_internal: returning with: -1413 (Unsupported card)
pkcs15-cardos.c:158:sc_pkcs15emu_cardos_init: sc_pkcs15_bind_internal failed: -1413 (Unsupported card)

Another attempt:

pkcs15.c:993:sc_pkcs15_bind_internal: bind to application('(null)',aid:'A000000851000014')
pkcs15.c:1013:sc_pkcs15_bind_internal: application path '3f000102'
...
apdu.c:367:sc_single_transmit: CLA:0, INS:A4, P1:8, P2:C, data(2) 0x7ffd60019ab2

is successfull. Then:

pkcs15.c:1039:sc_pkcs15_bind_internal: absolute path to EF(ODF) 3f0001025031
card.c:844:sc_select_file: called; type=2, path=3f0001025031
...
[pkcs15-tool] apdu.c:367:sc_single_transmit: CLA:0, INS:A4, P1:8, P2:0, data(4) 0x7ffd60019ab2

again ends up with (final) fail:

card-cardos.c:485:cardos_check_sw: file not found
iso7816.c:627:iso7816_select_file: returning with: -1201 (File not found)
card-cardos.c:660:cardos_select_file: returning with: -1201 (File not found)
card.c:866:sc_select_file: 'SELECT' error: -1201 (File not found)
pkcs15.c:1050:sc_pkcs15_bind_internal: EF(ODF) not found in '3f0001025031'
pkcs15.c:1205:sc_pkcs15_bind_internal: returning with: -1413 (Unsupported card)
...
pkcs15.c:1306:sc_pkcs15_bind: returning with: -1413 (Unsupported card)
  1. eidklient sends a lot of other data but I haven't found any resemblence between those and pkcs15-tool and I don't want to expose data from my ID if I don't know what they mean.

Edit: well, I have realized that I haven't issued exactly the same commant for those apps. While in one case I tried to dump all info, original eidklient just queried existence of the card and probably got it ready for authentication.


I've tried to run npa-tool couple of times without any sucess - it always ends without any output nor error. I plan to look into recompilation of openssl on Debian which I found somewhere around.


I'm not sure if this is only a slight deviation from Polish/German card or something that would need much deeper investigation. Could anybody give a hint please?


[1] https://www.minv.sk/?tlacove-spravy&sprava=platnost-certifikatu-pre-vydavanie-e-podpisu-na-obcianskych-preukazoch-a-cudzineckych-dokladoch-konci-26-juna-pouzivat-vydane-certifikaty-vsak-bude-mozne-az-do-konca-roku-2022

[2]

app default {
	framework pkcs15 {
        pkcs15emu = cardos;
        builtin_emulators = cardos;
	}
	card_atr 3b:d2:18:00:81:31:fe:58:c9:04:11 {
		driver = cardos;
	}
}

@jurajsarinay
Copy link
Contributor

I believe to have a card identical to the one mentioned by @scrool. I got it working by stitching together and slightly modifying pieces of code found within OpenSC.

https://github.com/jurajsarinay/OpenSC/tree/skeid

In a few weeks Slovakia will start issuing dual interface cards, likely based on CardOS 6.0. The v5.4 cards issued today remain valid until mid-2031, supporting them makes sense.

The card carries PKCS 15 structures OpenSC cannot parse, probably because parts of the CIAs are indeed invalid. The information from my card can be found here: skeid_v3.tar.gz

The files appear not to differ between cards (my sample size is of course rather limited). Instead of examining why exactly the (internal) binding fails, I find it easier to hard code the few necessary parameters in a new emulator. The most recent software provided by the government does not parse (or even read) the PKCS 15 structures either.

The card supports, but does not require PACE (or SM) for the operations I am interested in. There are (at most) 3 keys & certificates, a single mechanism (RSA-PKCS) and two PINs that result in two slots. The following operations (via PKCS 11) work reasonably well:

  1. signing with the RSA key tied to the qualified certificate (id: 01). Enter KEP PIN (possibly twice, due to CKA_ALWAYS_AUTHENTICATE). Note that although the proprietary PKCS 11 module requires BOK (user PIN) first, the card itself does not.
  2. signing with the RSA key tied to the "ordinary" certificate (id: 02). Enter BOK only.
  3. decryption with the RSA key tied to the encryption certificate (id: 03). Enter BOK only.

I miss PSS and OAEP, cannot get the card to do raw RSA.

PUK and unblocking features were omitted on purpose.

Feedback welcome.

@andrewshadura
Copy link

Wow, that’s a great analysis.
I’m getting a new residence card in the coming weeks, if there’s any easy way to inspect what’s in it when I get it, please let me know @jurajsarinay.

@jurajsarinay
Copy link
Contributor

The official e-ID client produces very useful logs once you enable debug tracing.

Edit ~/.eID_klient/config.json as follows (tested with v4.1):

{
    "log": {
    "logToFile": true,
    "logFromLevel": "LogLevel_Debug",
    "plainApduToFile": true,
    "verboseFile": true,
    "secApduToFile": true}
}

When you interact with the GUI application or use the proprietary PKCS11 module, log files show up in ~/.eID_klient/.

This way you can inspect several other functions the program performs (such as sign-on, arguably out of scope of this issue or OpenSC).

Once you have an idea what you want from the card, opensc-explorer does the job.

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

No branches or pull requests

8 participants