Czytanie ELS przez interfejs stykowy

By | 2008/04/20

Poniższy artykuł jest krótkim opisem moich eksperymentów z ELS. Mam nadzieję, że pomoże rozpocząć zabawę z kartami 7816, które z jednej strony są już zastępowane przez karty z interfejsem bezstykowym, z drugiej (głównie ze względu na bezpieczeństwo i pobór mocy) wchodzą do naszego życia codziennego.

Co to jest ELS?

ELS, czyli Elektroniczna Legitymacja Studencka jest kartą chipową zawierającą informacje o studencie podpisane kwalifikowanym podpisem elektronicznym przez wydawcę. Dokładne informacje na temat wyglądu nośnika jak i zawartości można znaleźć w odpowiednim rozporządzeniu. O samej legitymacji i przygodach związanych z jej wdrażaniem można przeczytać na stronie VaGli:

Karta powinna być zgodna ze standardem ISO 7816, a dane na niej zawarte powinny być zapisane w formacie ASN.1 Basic Encoding Rules zgodnie ze specyfikacją w załączniku nr 3 do rozporządzenia. Nie znalazłem szczegółowych informacji na temat interfejsu bezstykowego, ale z wiarygodnego źródła wiem, że ELSki wyposażone w interfejs Mifare pozwalają na odczytanie danych związanych z legitymacją (imię, nazwisko, nr albumu, PESEL) każdemu bez żadnego uwierzytelniania. Nie mam jeszcze sprzętu do czytania kart RFID 13,56MHz (w tym Mifare), ale w najbliższym czasie powinienem mieć dostęp do odpowiednich czytników.

Sprzęt

Do zabaw z kartami chipowymi używam bardzo starego czytnika do kart stykowych Schlumberger Reflex USB, który nabyłem okazyjnie na allegro. PCSC-lite pozwala mi rozmawiać z tym sprzętem na odpowiednio wysokim poziomie i do tego ma API niemal identyczne z Windowsowym PCSC (łatwiej będzie przeportować).

Zawartość karty

Pierwsza wersja programu odczytującego służyła do skanowania karty w poszukiwaniu wybieralnych plików. Dane na każdej karcie stykowej zgodnej z ISO 7816 są ułożone w strukturę drzewiastą. Odpowiednikami katalogów są pliki DF (Dedicated File – czasami nazywane Directory File), rolę plików zwykłych pełnią pliki EF (Elementary File), każdy plik ma 2 bajtowy adres. Korzeniem drzewa jest plik 0x3F00, oznaczony jako MF (Master File). Oprócz tego zarezerwowane są adresy 0x3F00 (obecny katalog, odpowiednik ‘.’) i 0xFFFF. Wszystkie DFy dostępne z MF muszą być zarejestrowane (aby uniknąć kolizji w przypadku więcej niż jednej aplikacji na jednej karcie) i szczerze mówiąc nie wiem gdzie znaleźć ich spis :) (najprawdopodobniej jest dostępny za drobną opłatą u podmiotu rejestrującego).

Przeskanowanie ujawniło następujące pliki DF:

  • 0x0101 (DF.SELS) – Elektroniczna Legitymacja Studencka
    • 0x0001 TRANSPARENT (EF.CERT) – kwalifikowany certyfikat emitenta
    • 0x0002 TRANSPARENT (EF.ELS) – plik z danymi legitymacji + podpis
  • 0x5011 DF – nieznany
    • 0x8001
    • 0x8002
    • 0x8003
    • 0x8004 hic sunt dracones
    • 0x8005
    • 0x8006
    • 0x8007

Skanowanie wszystkich 65535 możliwości trwało około 4h. Jeżeli chodzi o DF 0x5011 jest on najprawdopodobniej interfejsem do wgrywania aplikacji na kartę.

Wyjaśnienie kodu programu

Nie będę tutaj opisywać inicjalizacji komunikacji z kartą, szczegóły można znaleźć w dokumentacji ISO. Kod załączony do artykułu wywołuje wszystkie funkcje potrzebne do połączenia i pracy z kartą przez interfejs PCSC. Pozwala też na łatwą modyfikację i automatyzację niektórych działań (licencja GNU GPLv3).

Ogólna struktura komend wysyłanych do karty chipowej ma następującą postać (kolejne bajty numerowane od 0):

0 1 2 3 4… ostatni
CLA INS P1 P2 pola opcjonalnych danych Le

gdzie CLA to klasa komend (przyjąłem 0x00 – patrz ISO 7816-4 5.4.1), INS to bajt wskazujący instrukcję, a P1 i P2 to dwa parametry komendy. W przypadku, gdy komenda wymaga wysłania więcej niż dwóch bajtów danych (np. zapis do pliku) stosuje się pola opcjonalne, z których pierwszy bajt opisuje długość, a pozostałe zawierają konkretne dane. Ostatnim polem jest Le, które najczęściej podaje liczbę bajtów jaką jest w stanie przyjąć nasz czytnik kart.

Aby odczytać zawartość pliku na karcie, musimy go najpierw wybrać przy pomocy komendy SELECT FILE (0xA4), która przyjmuje 2 parametry określające sposób wyboru pliku (my wybieramy na podstawie identyfikatora i nie interesuje nas na razie jakie informacje zwróci komenda – P1 = 0x00 i P2 = 0x00). Następnie podajemy długość danych (0x02) i same dane, czyli identyfikator pliku (np. 0x0101), bajt Le zostawiamy pusty (nie wysyłamy go).

Po wybraniu odpowiedniego pliku odczytujemy jego zawartość za pomocą komendy READ BINARY (0xB0), która przyjmuje przesunięcie danych w pliku jako jeden parametr zajmujący P1 i P2 (2 bajty), a bajt Le wskazuje liczbę danych jakie jesteśmy w stanie przetworzyć.

Jeżeli kod nadal nie jest czytelny proszę o kontakt. Zaznaczam jednak, że nie udzielam lekcji z podstaw programowania w języku C, ani nie zajmuję się tłumaczeniami standardów ISO na polski :). W następnym artykule na temat ELS postaram się opisać strukturę samego pliku danych i certyfikatu oraz zaprezentować weryfikację podpisu legitymacji.

Uaktualnienie

Jak się okazuje same dwubajtowe identyfikatory plików (FID) nie muszą być globalnie takie same. Poniższą, uniwersalną metodę selekcji DF.SELS przesłał Krzysztof Rutecki z Wrocławia, za co serdecznie dziękuję. Preferowanym sposobem wyboru DF.SELS (najprawdopodobniej także DFów innych aplikacji) jest AID (Application ID), który to właśnie znajduje się w odpowiednim załączniku do piątej części ISO7816 i jest zarezerwowany tylko dla danej aplikacji. Pełna komenda wybierająca DF.SELS przez AID znajduje się w funkcji “selectDfselsByAID” nowego kodu źródłowego. Jest to zwykły SELECT FILE, tyle że P1=0x04, a P2=0x00, później znajdziemy długość AIDu w bajtach i sam AID. Ten sposób powinien zagwarantować zgodność oprogramowania z legitymacjami innymi niż te z Poznania.

Linki

Załącznik do artykułu: els_reader.tar.gz

Łukasz Kulasek napisał klasę w Javie służącą do odczytywania zawartości ELS.

10 thoughts on “Czytanie ELS przez interfejs stykowy

  1. Leopard

    Jak najprościej ugryźć weryfikację tak uzyskanych informacji? Uzyskano certyfikat, dane, podpis elektroniczny – która biblioteka to udźwignie? OpenSSL? GnuTLS?

    Reply
    1. Makdaam Post author

      OpenSSL poradzi sobie bez problemu. Z tego co pamiętam dane są zapisane w S/MIME “openssl smime -verify -inform DER -in dane.bin -cert cert.bin” powinno zadziałać. Niestety nie ma możliwości zweryfikowania czy certyfikat jest autentyczny (przynajmniej mi nie udało się uzyskać ścieżki podpisów do certyfikatu root CA Sigillum).

      Reply
  2. Robert

    W ELS przechowywany jest jeszcze jeden dodatkowy rekord z tzw. identyfikatorem jest to numer ktory znajduje się (jesli jest) na odwrocie ELS na kodzie kreskowym jak go odczytać ?? Oprogramowanie firm zajmujacych się dostarczaniem oprogramowania do ELS potrafi to robić. Czesto jest to wykorzystywane w bibliotekach jako tzw. numer biblioteczny

    Reply
  3. Makdaam Post author

    Szczerze mówiąc nie wiem :) ale odczytaj cały rekord danych z karty i zobacz czy nie ma dodatkowego pola. Oprócz pól obowiązkowych zawsze można dopisać dodatkowe z odpowiednim OIDem.

    Reply
  4. Paweł

    Trochę odkopuję kotleta, ale co zrobić jeżeli mój ELS (PGda) wysyła mi komunikat:
    ELS reader by Makdaam.eu
    ver 0.1.1

    Establishing context… done
    Getting readers… done
    Gemalto PC Twin Reader 00 00
    Connecting to reader ‘Gemalto PC Twin Reader 00 00’…done
    Active protocol: T0
    Selecting root
    Selecting file 3F 00

    Error: Card protocol mismatch.

    Jak mam go zmusić do komunikacji? Próbuję zrobić takie małe sprytne urządzenie do odczytywania danych i ono się opiera na Raspberry Pi z wgranym Raspbianem (Debian armhf). Wszystko mam poinstalowane, PCSC_scan podaje poprawne wyniki przy odczycie kart, więc skąd się bierze error w tym programie?

    Reply
    1. Makdaam Post author

      Ten temat po to jest, żeby go odkopywać :) ELS się zmieniają. Co do protocol mismatch to bym sprawdził czy dobrze jest wybrane T0/T1 (T1 dodatkowo opakowuje dane wysyłane pomiędzy kartą, a czytnikiem i sprawdza ich dokładność). Nie pamiętam teraz czy mój soft explicite ustawia T0/T1, jeżeli tak, to pewnie gdzieś w kodzie trzeba zmienić protokół na T1.

      Sprawdzę wieczorem.

      Reply
      1. Paweł

        Przestawiłem w kodzie na T0 (bo czytał T1 i stąd ten error) i teraz w plikach bin spodziewałem się ciągu hex, a dostałem dziwną “zakodowaną” wiadomość i niestety z drugiego artykułu program nie radzi sobie z odczytaniem tego.
        Podobnie jest z certyfikatem: $ openssl asn1parse -inform DER -in cert.bin -i
        Error in encoding
        3069375696:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:asn1_lib.c:142:

        Reply
        1. Makdaam Post author

          Zobacz czy “strings dane.bin” znajduje jakieś sensowne ciągi znaków. Powinno być co najmniej imię i nazwisko.

          Reply
  5. KamilD

    Czy jest jakiś znany powód, dla którego występuje:
    Selecting file 3F 00
    Error: Unknown error: 0xFFFFFFFF8010000F

    Zapewne nie bez znaczenia jest to:
    # opensc-tool -f
    SELECT FILE failed: Unknown data received from card

    Czy to oznacza, że ELSki z AGH są magiczne? :)

    Reply
    1. Makdaam Post author

      OpenSC to narzędzie do kart z API PKCS#11, ELS domyślnie takiego API nie musi wspierać (chociaż może).

      Co do odczytu danych: Jeżeli piszesz kod do odczytywania, to zajrzyj w mój kod źródłowy, w artykule jest opisana procedura, która nie musi działać ze wszystkimi kartami. Bezpieczniej jest otwierać DF.SELS po ID aplikacji (inne APDU).

      Edit: o, w OpenSC też są narzędzia niskopoziomowe.
      Nie wiem w jaki sposób opensc-tool robi listowanie plików. :) Rozumiem, że “opensc-tool –list-readers” pokazuje bez problemu Twój czytnik?

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *