Tartalmi kivonat
Szakdolgozat GNU fejlesztésű programba integrált, intelligens kártyára alapozott autentikáció ELTE, programozó-matematikus szak, nappali tagozat Készítette: Lusztig Péter Témavezető: Kincses Zoltán Budapest, 2004. március 20 1 2 Tartalomjegyzék Szakdolgozat - Lusztig Péter: GNU fejlesztésű programba integrált, intelligens kártyára alapozott autentikáció . 1 Tartalomjegyzék . 3 Bevezetés . 7 I. Felhasználói dokumentáció 9 1. A feladat rövid megfogalmazása 9 1.1 Magas szintű programnyelvek 9 1.2 GSM SIM kártyák 9 1.3 Biztonsági megfontolások 10 1.31 Fizikai biztonság 10 1.32 Logikai biztonság 10 1.4 Az alkalmazott megoldás 11 2. A program használatához szükséges információk. 13 2.1 Gsview32exe 13 2.2 Cardlistexe 14 2.3 VC6Sampleexe 16 3. A felhasznált módszerek rövid ismertetése . 22 3.1 3.2 3.3 3.4 3.5 3.6 3.7 Microsoft Visual Studio . 22 Microsoft Foundation Classes. 23 NMAKE. 23 Towitoko. 24 ScardServer . 24 ETSI
. 26 CSP . 27 II. Fejlesztői dokumentáció 28 4. A feladat részletes specifikációja 28 4.1 A GSM SIM kártyák* . 28 4.11 Az intelligens kártyák fizikai paraméterei (ISO7816-1) 29 4.12 Az intelligens kártyák mérete és az érintkezők helyzete (ISO7816-2) 30 4.13 Az intelligens kártyák elektromos jelei és az átviteli protokollok (ISO7816-3) 31 4.14 Az intelligens kártyák által értelmezett parancsok (ISO7816-4) 33 4.141 Definíciók 33 4.142 Rövidítések 34 4.143 Jelölések 35 4.144 Adatszerkezetek 35 4.145 Biztonság 37 4.146 APDU-k 37 4.147 Válasz APDU 39 4.2 Biztonsági megfontolások* . 42 4.21 Az alkalmazás ellen irányuló támadások 43 4.211 Fizikai szint 43 4.212 Logikai szint 44 4.22 A kártya ellen irányuló támadások 45 4.23 A terminál ellen irányuló támadások 46 4.24 Az operációs rendszer ellen irányuló támadások 47 4.25 Az autentikációs állomány ellen irányuló támadások 47 5. A felhasznált módszerek részletes
leírása. 49 5.1 A Microsoft Visual C++ 6 és a Microsoft Foundation Classes* . 49 5.2 Scard* . 59 5.21 Áttekintés 59 5.22 Az Scard interfész 60 5.23 DLL függvények 60 5.24 Kártyastátusz 62 5.25 Több alkalmazás esete 64 3 5.26 Hibakódok 64 5.27 Utasításkészlet 65 5.271 System,Info 69 5.272 System,SetLng 69 5.273 Card,APDU 70 5.3 ETSI szabványok 72 5.31 GSM 1111* . 72 5.311 Általános információk 72 5.312 SIM utasítások 75 5.313 Visszatérési értékek 81 5.314 Fájlszerkezet 82 5.32 GSM 0411* . 87 5.33 GSM 0340* . 89 5.331 Általános működési elv 89 5.332 Short Message elemek 90 5.333 Adatblokk mezők 91 5.334 SMS-DELIVER 96 5.335 SMS-SUBMIT 97 5.34 GSM 0338* . 98 5.341 SMS Data Coding Scheme 98 5.342 Karakterkészlet 99 5.4 CSP* . 101 5.41 Cryptographic Service Provider jellemzői 101 5.42 CSP függvények 104 5.421 CryptAcquireContext 105 5.422 CryptCreateHash 106 5.423 CryptDecrypt 107 5.424 CryptDestroyHash 107 5.425 CryptEncrypt 107
5.426 CryptDeriveKey 108 5.427 CryptHashData 108 5.428 CryptDestroyKey 109 5.429 CryptReleaseContext 109 5.43 CSP adattípusok 110 III. A program forrásnyelvi listája 112 6. Intelligenskártya-támogatással kiegészített GSView 36 verzió Visual C++ 6 nyelvű forráskódja. 112 6.1 Általam létrehozott új fájlok (13 darab) 112 6.2 A módosított korábbi fájlok (10 darab) 113 6.3 A forrásnyelvi listák elemzése* . 113 6.31 Gvwincpp 113 6.32 Secureh 114 6.33 Securecpp 114 6.34 Gvcrch 118 6.35 Degvclangrc, Engvclangrc, Esgvclangrc, Frgvclangrc, Itgvclangrc 118 6.36 Scardh 119 6.37 Scardcpp 121 6.38 Scindlgh 125 6.39 Scindlgcpp 125 6.310Secure1rc 127 6.311Resourceh 128 6.312Gvwin2rc 128 6.313S crypth 128 6.314S cryptcpp 129 6.315Extrbin 132 6.316Gvwinvcmak 132 6.317Gvwincmak 133 6.318 buildbat 134 4 7. Az autentikációs állományt létrehozó Cardlist program Visual C++ 6 nyelvű forráskódja. 135 7.1 A létrehozott fájlok (20 darab) 135 7.2 A
forrásnyelvi listák elemzése* . 135 7.21 Cardlistdsw 136 7.22 Cardlistdsp 136 7.23 Cardlistcpp 138 7.24 Cardlisth 140 7.25 Cardlistrc 140 7.26 resourceh 144 7.27 StadAfxcpp 144 7.28 StdAfxh 145 7.29 CardlistDlgcpp 145 7.210CardlistDlgh 158 7.211CodeDlgcpp 159 7.212CodeDlgh 160 7.213FileCodeDlgcpp 161 7.214FileCodeDlgh 162 7.215Scardcpp 163 7.216Scardh 163 7.217res/Cardlistrc2 163 7.218Cardlistico 164 8. A GSM SIM kártya karbantartására szolgáló VC6Sample magyar verziójú Visual C++ 6 nyelvű forráskódja. 165 8.1 A létrehozott fájlok (19 darab) 165 8.2 A forrásnyelvi listák elemzése* . 166 8.21 VC6Sampledsw 166 8.22 VC6Sampledsp 166 8.23 VC6Samplecpp 168 8.24 VC6Sampleh 170 8.25 VC6Samplerc 170 8.26 resourceh 174 8.27 StdAfxcpp 175 8.28 StdAfxh 175 8.29 VC6SampleDlgcpp 175 8.210VC6SampleDlgh 205 8.211EditDlgcpp 206 8.212EditDlgh 210 8.213Scardcpp 211 8.214Scardh 211 8.215res/VC6Samplerc2 211 8.216res/VC6Sampleico 212 8.217Scarderr 212 IV. Mellékletek
213 9. Licencszerződés 213 Aladdin Free Public Licence. 214 0. Subject Matter 214 1. Licences 214 2. Restrictions 215 3. Reservation of Rights 216 4. Other Restrictions 216 5. Limitations 217 6. General 217 Aladdin szabad felhasználói licencszerződés. 218 0. 1. 2. 3. 4. A szerződés tárgya. 218 Licenc jogok . 218 Korlátozások. 219 Jogi fenntartások. 220 További fenntartások . 220 5 5. Korlátozások 221 6. Általános érvényű rendelkezések 221 10. A CD-melléklet tartalma 222 10.1 10.2 10.3 10.4 10.5 11. 12. 13. 14. Adathordozó főkönyvtár. 222 A Cardlist alkönyvtár . 222 A GSView alkönyvtár . 223 A VC6Sample alkönyvtár. 225 Az Egyéb alkönyvtár . 226 Tapasztalatok . 227 Köszönetnyilvánítás . 228 Irodalomjegyzék. 229 Szószedet . 230 * A megjelölt fejezetek olyan részeket tartalmaznak, amelyek csak a CD-mellékleten található verzióban szerepelnek. Így az oldalszámok emiatt eltérhetnek a két verzió között 6 Bevezetés
Jelen szakdolgozat az ELTE Informatikai Kar, programozó-matematikus szak államvizsgájához készült „GNU fejlesztésű programba integrált, intelligens kártyára alapozott autentikáció” címmel. A dolgozat rendkívül sok szakkifejezést tartalmaz. Néhány ezekből eléggé közismert ahhoz, hogy magyar megfelelője legyen, sokkal több azonban, amelyet a magyar nyelvű szakszövegek is eredeti formájában vagy csupán magyarítva, kiejtés szerint írnak le. Figyelembe véve az utóbbi idők tendenciáit az egyetemen is elérhető külföldi szakkönyvek fordításaiban, megpróbáltam igazodni ezekhez az új kifejezésekhez Sajnos azonban sok helyen nincs egységes elnevezés sem, például a „directory” kifejezést lehet „könyvtárnak”, „alkönyvtárnak”, de még „mappának” is fordítani. Ahol lehetett és volt értelme (és nem tűnt túlzottan bizarrnak egy elnevezés) ott megpróbáltam az idegen kifejezéseket magyarra fordítani, sok helyen
zárójelben feltüntetve az eredeti kifejezést is. Az intelligens kártyák használata csupán néhány évtizedes múltra tekint vissza, az utóbbi években azonban immár Magyarországon is megszokott dolog. Nap mint nap használjuk őket, mint egyes bank-, telefon-, mobiltelefon-kártyák (SIM), diákigazolvány, nem beszélve a számtalan kereskedelmi cég „pontgyűjtés”-re használható kártyáiról, melyek közül néhány szintén alkalmas banki szolgáltatásokra. A Bull cég 1979-ben elkészítette el ugyan első, mikroprocesszorral is rendelkező kártyáját, mivel azonban itt a processzor még külön chipen helyezkedett el, a megoldás nem bizonyult kellően megbízhatónak. A technikai fejlődés következtében csak a 80-as években vált lehetővé az összes áramkör egyetlen chipbe való integrálása, melyet Franciaországban valósítottak meg. A mai napig Franciaország a legjelentősebb ország a chipkártya gyártása szempontjából, az új
diákigazolvány is a francia Gemplus cég terméke. Az chipkártyák „intelligencia” terén igen különböző képességekkel rendelkezhetnek. Alapvetően két típust különböztethetünk meg: a csak adattárolásra alkalmas (memóriakártya), illetve az önálló számítási és feldolgozási kapacitással is rendelkező kártyákat (processzorkártya). Ezek abban különböznek egymástól, hogy a kártya csak memóriaegységet vagy mellette processzort is tartalmaz Csak az utóbbiakat lehet programozni, vagy felhasználói programok futtatására alkalmazni. Ebből adódik, hogy egy processzorkártya tulajdonképpen egyenértékű egy lassú számítógéppel, csupán az input-output perifériákban különböznek. Egyetlen úton tud kommunikálni a külvilággal: a kártyaolvasón keresztül (Ma már léteznek megoldások a vezeték nélküli kommunikációra, amikor az elektromágneses indukció révén keletkező pillanatnyi elektromos áramot felhasználva, egy
rádiójel segítségével kommunikál a kártya a külvilággal, ehhez csak el kell vele haladni az erre kiképzett „olvasó” közelében. Azonban ez a verzió még nem túl elterjedt) Az „intelligens kártya” szó angol megfelelője a „smartcard”, és sokszor magyar szövegkörnyezetben is így találkozhatunk vele. A kártya kibocsátója az intelligens kártyán különféle fájlstruktúrát definiálhat, s minden fájlhoz megadhatja a hozzáféréshez szükséges jelszavakat, jogosultságokat. A kártya felhasználója ezek után különböző kártyaolvasókban használja a kártyáját, és különböző 7 műveleteket végez a kártyán található adatokkal, s nemcsak olvashatja, de megfelelő jogosultságok esetén írhatja is őket. Egy processzorkártya esetén (pl. SIM) azonban a kártyán lévő adatokon nem a kártyaolvasó, vagy az olvasóhoz kapcsolódó számítógép végez műveleteket, hanem a kártyán futó szoftver maga. A szoftver rendelkezik
egy megfelelő interfésszel, és csak ezen át léphetünk kapcsolatba a kártyával. A kártya kibocsátója már előre definiálta ezt az alkalmazást, s azt nem is lehet megváltoztatni a későbbiekben sem Ezt a fajta védelmi mechanizmust tekintettem az általam implementált autentikáció alapjának, melynek során bizonyos meg nem változtatható, és szabvány szerint egyedi kártyaazonosítók felhasználásával történik az illetékesség megállapítása. A témabejelentőn vállalt feladatoknak teljes mértékben sikerült eleget tenni. A Towitoko ChipDrive Micro Fun kártyaolvasó rendszerét használva C programnyelvű környezetben megoldottam a sokak által ismert Aladdin GhostView Windows operációs rendszeren működő verziójának („GSView32”) intelligens kártyával történő azonosítását. Habár a program nem kifejezetten GNU licenc alapján érhető el, azért még szabadon hozzáférhető forráskódú, csak üzleti célokra nem használható fel
(Aladdin Free Public License). A Gemplus cég intelligens kártyái helyett a Magyarországon beszerezhető mobiltelefon-kártyákat használtam fel Az általános séma felállítása, hogy minél kevesebb módosítással bárhová beépíthető azonosítás legyen elérhető, sikerült, sőt a kidolgozott modul olyannyira sokoldalú, hogy teljes körű alkalmazásának szemléltetése végett (és egy esetleges sokkal hatékonyabb, biztonságosabb autentikáció kidolgozásának elősegítésére) egy különálló SIM kártya karbantartó programot (VC6Sample) is bemutatok. A létrejövő szoftverek egyaránt nyilvános forráskódúak, apró eltérés, hogy a továbbfejlesztett „GSView” a már említett Aladdin Free Public License alapján használható fel. Nem sikerült azonban azon „álmom”, mert ma már inkább csak álomnak nevezhetnénk bármely, az új diákigazolvánnyal kapcsolatos tervet, hogy diákigazolványon alapuljon az autentikáció. Egyrészt a
diákigazolvány specifikációja nem publikus, másrészt korántsem aratott akkora sikert sem üzleti, sem kormányzati körökben a diákigazolvány által felhasználható számos lehetőség kiaknázása, így nem áll rendelkezésre a megfelelő számú, speciálisan diákigazolvány olvasására alkalmas rendszer. A GSM SIM kártyáktól eltérően ugyanis az új diákigazolvány úgynevezett kétkártyás rendszer, minden kártyaművelethez szükség van egy SAM-re (Secure Access Module), ez nagyban megnöveli a biztonságot Pedig az eredeti célkitűzések, miszerint a számítógépes laborokat tényleg „csak az ITK hallgatói használhatják”, amint az kiírva van, megvalósítása még mindig aktuális, sőt! 8 I. Felhasználói dokumentáció 1. A feladat rövid megfogalmazása Az intelligens kártyák a bevezetőben említettek alapján viszonylag kis erőforráskészlettel rendelkeznek. Ma, a miniatürizálás korában, amikor 3-4 cm nagyságban 1 Gigabájtos
adattároló eszközök léteznek (USB Pen Drive), az intelligens kártyák néhány tíz kilobájtnyi memóriája viszonylag kevésnek tűnik, ne feledkezzünk meg azonban a kártya szinte elhanyagolható kiterjedésű vastagságáról, miáltal könnyen elfér egy tucat is egy átlagos pénztárcában. És manapság, amikor egyre kisebb mobiltelefonokat gyártanak, nem megengedhető, hogy a SIM (Subscriber Identity Module) kártya miatt kelljen nagy készülékeket gyártani. (Így vált szabvánnyá a korábbi, bankkártya méretű SIM kártyák helyett a kisebb, 25x15 mm-es SIM kártya.) A kártyák processzora is viszonylag lassú, s egy bizonyos határnál nyilvánvalóan nem lehet nagyobb, mivel a műanyag tokban igen nehéz megoldani a kellő hűtést. 1.1 Magas szintű programnyelvek Mivel a kártyakibocsátók rettegnek attól, hogy elkötelezik magukat egy kártyatípus mellett, s ezzel kiszolgáltatottá válnak az adott gyártóval szemben, logikus megoldásnak tűnt a
szinte mindenhol használható Java nyelvet alkalmazni, hiszen a nyelv platformfüggetlen, másrészt egy Java applet kellően kicsi. A Java Card API is az objektum orientált szemléletet követi Minden egyes applet, amit a kártyára letöltünk, egyegy objektum, amely önálló életet él Rendelkezik attribútumokkal és metódusokkal A külvilág számára látható metódusok pedig argumentumként egy APDU-t (Application Data Unit - az az adategység, amit a PC küld el a kártyának egy csomagban) kap. Ezek alapján egy Java Card alkalmazást úgy lehet a kártyára telepíteni, hogy első lépésben a programozó megírja a programot, s lefordítja egy tetszőleges Java fordítóval. Ezek után szükség van egy kártyaspecifikus konvertáló programra, amit minden kártyagyártó a saját kártyájához ajánl. Az így kapott gépi kódú program a kártyára feltöltve már teljesen kifogástalanul működik. Másik megközelítést alkalmazott a Microsoft, mikor a WinCard
rendszerét implementálta. 1998-ban született meg a Smartcard for Windows rendszer A tervek szerint az intelligens kártyák szerves részét fogják képezni a jövő Windowsos rendszerének, szerepük lesz bejelentkezéskor, az Outlook részeként az üzenetek hitelesítésében, valamint az elektronikus kereskedelemben. Az ő kártyáik Visual Basicben programozhatóak, illeszkedvén a Windowsos világképhez 1.2 GSM SIM kártyák Az előzőeken kívül is léteznek különböző szabványok az intelligens kártyákra vonatkozóan, a legelterjedtebb azonban a mai napig a Java Card. A GSM SIM kártyák is Java technológiát használnak, üzenetkezelésre az „ISO/IEC 7816 Part 4” által definiált APDU-kat használják. A fentiekben vázoltakon kívül a SIM kártyák alkalmazása során egy közbenső fázis kerül beépítésre: miután a kártyagyártó az alkalmazásokat rögzíti a kártyán és az a végfelhasználóhoz kerülne, közbeiktatnak egy ún.
„adminisztrációs fázist” Ennek során rögzítenek bizonyos telefonszolgáltató-specifikus paramétereket Azután, mielőtt a kártyát kibocsátanák, egy bizonyos adatmező, az 9 ADMINISTRATION DATA FIELD fájl értékét a kártyán nem adminisztrációs fázisra állítják, így semmilyen, csak az adminisztrációs fázisban változtatható fájl értéke nem módosítható többé. A mobiltelefónia és azon belül a SIM kártyák világát Európában a European Telecommunications Standards Institute (ETSI) által kiadott szabványok definiálják. Ez biztosítja, hogy minden mobilszolgáltató szolgáltatása minden telefonkészülék-gyártó készülékével és minden chipkártyagyártó intelligens kártyájával kompatibilis legyen. Ezek a szabványok mondják ki, hogy minden SIM kártya 20 jegyű sorozatszáma (IC CARD IDENTIFICATION) már az adminisztrációs fázis előtt, tehát ahogy lejött a futószalagról, rögzítésre kerül, és az egyedi minden
kártyára nézve. Az első hat jegy alapján, mivel a sorozatszám általában a SIM kártya hátoldalán is szerepel, a mobiltelefonszolgáltató is megállapítható Szintén egyedi, azonban már nem publikus, mivel a felhasználót a hálózaton azonosítja, a kártya 15 jegyű International Mobile Subscribing Identifier (IMSI) száma. Ezt az adminisztrációs fázis során rögzítik a kártyán, és a szolgáltatók érdeke, hogy egyedi legyen, ugyanis ennek alapján fizetjük a telefonszámlát Ezt a két információt tárolom egy titkosított adatbázisban, és amint az azonosításra váró program elindításra kerül, összehasonlítja az aktuális kártya ezen adatait az adatbázisban lévővel, és csak egyezés esetén engedi továbbfutni a programot. 1.3 Biztonsági megfontolások A lehetséges támadások alapvetően két csoportra oszthatók aszerint, hogy a támadás a kártya fizikai vagy logikai szintjét veszi célba. Ennek megfelelően beszélhetünk fizikai
és logikai biztonságról. 1.31 Fizikai biztonság A fizikai biztonság elleni támadásnak több módja is van, a biztonsági megfontolások függvényében különböző védelmi mechanizmusok alkalmazása javasolt. Például egy kártya fizikai manipulálásához rendszerint igen komoly és költséges felszerelésre van szükség (mikroszkóp, lézeres vágóberendezés stb.), ami csak nagyon keveseknek áll rendelkezésre. Ennek ellenére fel kell arra készülni, hogy valakinek sikerül celláról cellára kiolvasni az EEPROM tartalmát, így a legfontosabb információkat (pl PIN) a fizikai biztonság ellenére célszerű kódolva tárolni Mindenesetre ez technológia kérdése, és a kártya fizikai biztonságának megvalósítása a kártyagyártó feladata. 1.32 Logikai biztonság Logikai biztonság elleni támadásról akkor beszélünk, ha a kártya „szétszedése” nélkül próbáljuk feltörni a rendszert. Ez többféleképpen megtörténhet, például ha a kártyát
ellopják, más kártyát használnak, szoftveresen szimulálják a kártyát stb Mindenesetre az autentikáció során nemcsak a kártya, hanem a felhasználó ellenőrzésére is szükség van. Különféle biometrikus eszközök hiányában a PIN kódra kell hagyatkoznunk. (A PUK kód sajnos csak új PIN kód megadásával egyetemben alkalmazható, így sajnos használata kényelmetlen.) 10 1.4 Az alkalmazott megoldás A megvalósított CScard nevű osztályban olyan függvényeket deklaráltam, amelyeket az ETSI specifikációi szerint a mobiltelefonok használnak, hogy kommunikáljanak a kártyával, kiegészítve némi kényelmi funkcióval. Ennek alapján nyitva áll a kapu mindenféle biztonsági mechanizmus felállítása előtt, melyet a GSM szabvány támogat Például egyes RFU (=Reserved for Future Use - későbbi fejlesztésekhez fenntartva) fájlok használatával PIN kód által védett adatállományok állnak rendelkezésünkre, melyeket tetszés szerint
módosíthatunk. Operációs rendszer (Windows) Scard Server Futó alkalmazás (gsview32.exe) Kártyaolvasó (Towitoko ChipDrive Micro Fun) CScard Decrypt Chipkártya alkalmazás Kártyaadatok (extr.bin) Processzor Fájlszerkezet A gsview32.exe elindításakor meghívódik a WinMain függvény, ennek tartalmát módosítva lehetőségünk nyílik a fontosabb lépések megtétele előtt egy függvényhívással az általunk hozzáadott modulra terelni a vezérlést. Itt előállítjuk a CScard osztály egy példányát, mely az ScardServerrel kommunikál, amely a 32 bites Windowsra, a kártyaolvasó telepítésekor felinstallált háttérben futó processz Ez utasítja az operációs rendszert, hogy a soros porton (újabban már USB-n is) található kártyaolvasón végezzen műveletet. Az olvasó pedig az intelligens kártyán lévő alkalmazás megfelelő függvényeit használva teljesíti a kérést. A kapott kártyajellemzőket a Decrypt osztály egy példányának
segítségével összehasonlítjuk a jogosult kártyaadatokat tartalmazó fájllal. A modell felépítése nem véletlenül ilyen, a működő rendszert a biztonság szempontjából támadható komponensekre osztottam fel, mint a későbbiekben is látni fogjuk. A Cardlist alkalmazás egy, a modellben „Kártyafájl”-ként jelzett állomány létrehozására-módosítására szolgál, az egy listaként ábrázolva jelenik meg a dialógusablakban. Jelenlegi verziója a „GSView” elindításához szükséges autentikációs állomány létrehozására készült A betöltés-kimentés fájlműveleteken kívül a listához hozzáadás és listából törlés funkciók vannak megvalósítva. A kimeneti fájlt egy általunk megadott szóból generált kulccsal kódolja az operációs rendszer, amely implementációtól függetlenül minden számítógépen azonos eredményt ad, köszönhetően a Microsoft Cryptographic Service Providers-nek. 11 A VC6Sample a bevezetőben is
említetteknek megfelelően egy SIM kártya karbantartó alkalmazás. Létrehozásakor a cél, elsősorban a kidolgozott CScard osztály lehetőségeinek kiaknázása volt, másrészt azáltal, hogy a téma iránt érdeklődő mélyebben beáshatja magát a SIM kártyák világába, olyan biztonságtechnikai szemléletmódot alakíthat ki, melynek alkalmazásával a meglévőknél eredményesebb, a GSM SIM technológiára épülő autentikációs szoftvereket hozhat létre. Az implementált funkciók sokrétűek, de korántsem teljesek, magukban hordozzák a továbbfejlesztés szándékát. Jelenleg a PIN kód ki-be kapcsolása mellett a Saját számok, az SMS-ek és a Telefonszámok állományok menedzselésére van mód. A program figyeli emellett a kártyaolvasót, és ha új kártyát teszünk be, automatikusan frissíti a kijelzett kártyainformációkat. Az implementált szoftverek dialógus alapúak, ami azt jelenti, hogy nem a hagyományos ablakban futnak menüvel,
állapotsorral stb., hanem egy dialógusablak lesz a fő programablak (természetesen a GSView hagyományos ablakban fut, csak az ellenőrzés nem). 12 2. A program használatához szükséges információk 2.1 Gsview32.exe A program az Aladdin Ghostview 3.6 verziójának intelligens kártyára alapozott autentikációval kiegészített verziója. Számos értékes megjegyzés található az egyes forrásnyelvi listafájlok előtt, így bármilyen nem szigorúan vett felhasználói tevékenység előtt érdemes tanulmányozni a forráskódot is. Ezáltal nő a program érthetősége, és lecsökken a felmerülő hibalehetőségek száma A továbbiakban a szoftver kezelését bemutató rész következik Mint felhasználó, bizonyára sokan ismerik már az Aladdin Ghostview egyes verzióit. Tulajdonképpen ez az az ingyenes programtermék, mely Windows alapú rendszereken is elérhetővé teszi a PostScript formátumú fájlok használatát. Pont a termék viszonylagos
népszerűsége volt az ok, hogy rá esett a választásom, ezt láttam el autentikációs funkciókkal. A felhasználó számára az újonnan fejlesztett verzió látszólag semmiben nem különbözik a korábbitól. Alaposabb vizsgálat után tűnhet csak fel a gsview32exe néhány kilobájtnyi méretnövekedése. Annál nagyobb a különbség, amikor a szokásos „kérjük regisztráltassa” típusú üdvözlő ablak helyett a „Nem megfelelő vagy olvashatatlan kártya” tűnik fel. Nem elég ugyanis a Ghostview feltelepítése, rendelkeznünk kell egy kártyaolvasóval is. Mint a témabejelentőn is jeleztem a Towitoko ChipDrive Micro családú kártyaolvasók használatát vettem alapul A kártyaolvasó fizikai telepítése, majd a szoftverének felinstallálása egyben az ScardServer felinstallálását is eredményezi Annyit kell csak megtennünk, hogy telepítünk egy Towitoko kártyaolvasót A kezdeti erőfeszítéseink sikerének tudatában elindíthatjuk ugyan a
programot, de még mindig nem fog működni, a jogosult kártyaadatokat tartalmazó fájl ugyanis kezdetben csupán két, az én birtokomban lévő SIM kártya adatait tartalmazza. Ennél a pontnál ugorjunk a 2.2 Cardlistexe részhez, majd ha ott hozzáadtuk a saját SIM kártyánk adatait a többihez (vagy egy teljesen új fájlt is készíthetünk) akkor térjünk vissza ide! Másoljuk az extr.bin nevű fájlt abba az alkönyvtárba, ahová a Ghostview-t telepítettük, felülírván az eredetit! Helyezzük a megfelelő SIM kártyát a SIM adapterbe (annak a bankkártya-méretű eszköznek a közepén lévő kis nyílásába helyezhetjük a SIM kártyát, hogy használható legyen a kártyaolvasóban), majd azt az olvasóba, ha eddig nem tettük volna, és indítsuk el a gsview32.exe-t! Az sem gond, ha előbb indítjuk az alkalmazást, és csak azután tesszük be a kártyát, csak akkor a „Retry” - újrapróbál gombra kell kattintanunk. Ha biztosak vagyunk abban, hogy mindent
megfelelően hajtottunk végre, és mégis hibaüzenetet kapunk, próbáljuk meg a „Retry” gombot néhányszor, ha ez sem segít, akkor húzzuk ki, majd toljuk vissza a kártyát az olvasóba! Néha előfordul ugyanis, hogy a csúszóérintkezők nem érintkeznek megfelelően, vagy elmozdult a kártyánk stb. (Ha még ez sem segítene, akkor előfordulhat, hogy a kártyaolvasó inaktív, és aktiválni kell. Ehhez indítsuk el a CD-mellékleten az Egyeb alkönyvtárban található aktivbat fájlt, vagy kattintsunk a Windows Vezérlőpult Towitoko elemére, vagy a Start menüben a Programok mappában, ahová a Towitoko meghajtót telepítettük, indítsuk el a „Towitoko Update and Diagnostic Tool”-t, és detektáltassuk a kártyaolvasót! További információkért kérem olvassa el a Towitoko Súgójának megfelelő fejezeteit!) A 13 „Cancel” gomb megnyomására kilép a program, addig ugyanis nem indul el, amíg a megfelelő kártyát nem detektálja. Legegyszerűbb
esetben semmi különöset nem észlelünk, csak annyit, hogy felvillan a kártyaolvasó kijelzője, jelezvén az olvasást, majd pillanatnyi habozás nélkül elindul a Ghostview minden szokásos funkciójával. Ha a SIM kártyánkon nincs letiltva az elsődleges PIN kód használata (ez az alapbeállítás), akkor egy ablak jelenik meg, mely bekéri a PIN kódunkat. Vigyázat! Csakúgy, mint egy rádiótelefon esetében, a helytelen PIN kód blokkolhatja a kártyánkat! Ilyenkor csak a PUK kód segít! Jól vigyázzunk tehát, hogy ne adjunk meg hibás kódot, különösen azért, mert biztonsági megfontolásokból csak *-ok jelennek meg a számjegyek helyett! A maximálisan megadható jegyek száma 8, tekintve, hogy bizonyos kártyáknak 8jegyű PIN kódja van, ma Magyarországon azonban csak 4-jegyű PIN kóddal ellátott SIM kártyák vannak. Ha nem tudjuk a kódot, bármilyen következmény nélkül a „Cancel” gombot választhatjuk Az „OK” gombra kattintva azonban,
eltekintve attól, hogyha semmit sem adunk meg, megkezdődik az ellenőrzés függetlenül a PIN kód tartalmától. Ha hibás kódot adtunk meg, azt sem jelzi vissza a program, csupán a már megismert „Hibás vagy olvashatatlan kártya” üzenet jelenik meg. A megfelelő kód megadása esetén, ha minden rendben van, elindul a Ghostview 2.2 Cardlist.exe A Cardlist nevű alkalmazás segítségével szerkeszthetjük a „GSView”-hoz mellékelt extr.bin fájlt, vagy akár másikat is létrehozhatunk egy másik alkalmazás részére egy más nevű, más kulccsal kódolt verziót. Számos értékes megjegyzés található az egyes forrásnyelvi listafájlok előtt, így bármilyen nem szigorúan vett felhasználói tevékenység előtt érdemes tanulmányozni a forráskódot is. Ezáltal nő a program érthetősége, és lecsökken a felmerülő hibalehetőségek száma A továbbiakban a szoftver kezelését bemutató rész következik A program kezelése olyannyira egyértelmű,
hogy a legtöbb felhasználó azt néhány perc alatt elsajátíthatja. 14 A cardlist.exe elindítása után egy ablak fogad minket, melynek közepén egy háromoszlopos lista (kezdetben üres) helyezkedik el. Az első oszlop egyszerűen az épp aktuális sor sorszáma, a második oszlop az engedélyezett kártyák sorozatszámait, az utolsó pedig a hozzájuk tartozó IMSI számot tartalmazza. Az „Add” lenyomásával hozzáadhatjuk a listához az éppen bennlévő intelligens kártya adatait. Ha a PIN kód a kártyán nincs letiltva, akkor azt a megjelenő új ablakban meg kell adnunk. Itt is érvényesek mindazon megállapítások, melyek a 21 Gsview32exe fejezetben szerepelnek, miszerint a helytelen kód tönkreteheti a SIM kártyát Az esetlegesen fellépő hibákat felbukkanó üzenetablakok jelzik (hibás PIN kód, kártya nem olvasható stb.), vagy ha a „Cancel” gombra kattintunk, egy rövid figyelmeztetőüzenet jelenik meg, hogy a kártyaadatok eléréséhez
szükség van a PIN kódra A második „Remove” gomb egy listabejegyzés eltávolítását eredményezi. Először is jelöljünk ki a listából egy sort, annak sorszámára kattintva! Ezt láthatjuk a baloldali panelen. Azután kattintsunk a „Remove” gombra, s a lista újrarendeződik, immár nem tartalmazza a kijelölt sort. Egyszerre több sort is kijelölhetünk, s ekkor azok egyszerre kerülnek törlésre. (A több sor kijelölésének témakörében érdemes elolvasni a Windows Súgóját. Működő módszer például, hogy a kijelölendő sorokra a Ctrl nyomvatartása mellett kattintunk, vagy a Shift nyomvatartása mellett az adott sortól feljebb, illetve lejjebb lévőket a kurzormozgató billentyűkkel jelöljük ki.) 15 A „Load” gombra kattintva egy újabb dialógusablak jelenik meg. Itt adhatjuk meg a betöltendő fájl nevét, majd a kódolás kulcsát. A kódolás kulcsát biztonsági okokból mindkét mezőben meg kell adni. Természetesen a beírt
karakterek helyett csak *-ok jelennek meg. Ezután az „OK” gombra kattintva betöltődik a kívánt fájl, egyúttal törlődik minden eddigi elem a listából. Ha a fájl nem létezik, arról visszajelzést kapunk, sikeres betöltődés esetén a visszajelzés az újonnan betöltött lista lesz, mely felváltja a korábbi listaelemek helyét. Az utolsó „Save” gombra kattintva az előbbivel teljesen analóg módon a „File” dialógusablak ugrik elő, és annak kitöltése után (ha a jelszó és az ellenőrzése megegyezik) a megadott fájlnév alatt kerül elmentésre a kódolt lista. A sikeres mentésről visszajelzést kapunk. Ha a programból ki szeretnénk lépni, azt a már ismert módon az ablak címsorában található X gombra kattintva tehetjük meg. Ekkor, ha módosítottunk előtte a listán, a megváltozott listatartalomról egy újabb ablak tájékoztat, lehetőséget adva az elmentésre. A program kezeléséről elmondható, hogy a lehető legtöbb helyen az
előforduló hibákról hasonló formátumú hibajelentéseket kapunk. A fájlnév beírásánál nem csak a fájl nevét, hanem annak elérési útját is megadhatjuk, mind abszolút, mind relatív formában, vigyázzunk azonban arra, hogy ha az elmentendő fájl már létezik, azt a program kérdés nélkül felülírja. 2.3 VC6Sample.exe A VC6Sample egy SIM kártya karbantartó alkalmazás magyar nyelven. A SIM kártya menedzselő program jó szolgálatot tehet, hiszen például a kártyán lévő telefonszámainkat egyszerűen a Vágólapra helyezhetjük, majd valamely szövegszerkesztő programmal kinyomtathatjuk, elmenthetjük, kereshetünk benne, sorbarendezhetjük stb. A kitűzött célom mindenesetre az volt, hogy a programozók számára jelen szakdolgozaton kívül már semmilyen szakirodalomra ne legyen szükség a mobiltelefónia területén, kiegészítve persze a mellékelt szabványgyűjteménnyel. Mindenesetre érdemes megjegyezni, hogy ha a kártyaolvasó
rendszerünknek nem az alapkiépítésű, hanem egy hasonló képességű szoftverrel kiegészített verzióját vásároljuk meg, úgy kb. 50 euróval kell többet fizetnünk érte, és ez még nem tartalmazza a szoftver forráskódját. A program az általános kártyainformációk mellett a PIN kód ki-be kapcsolására, a Saját számok, a Telefonszámok és az SMS-ek szerkesztésére nyújt lehetőséget, sőt, ha a SIM kártyánk csak a szigorú értelemben vett ETSI szabványoknak tesz eleget, lehetőségünk van a már kitörölt SMS-ek elolvasására is (az újabb SIM kártyák már a törlést ténylegesen végre is hajtják, a 0xff kóddal töltik fel az állományt). Ez jól jöhet egy véletlenül kitörölt SMS-nél például A program szintén támogatja, hogy megváltoztassuk egy SMS feladójának telefonszámát, vagy ha az alfabetikus, akkor a feladó nevét, sőt új üzeneteket is alkothatunk, mintha csak kaptunk volna egyet. Fel kell hívnom azonban arra figyelmet,
hogy lépéseinknek jogi következményei lehetnek (Németországban már volt 16 példa fenyegető SMS bírósági per során történő felhasználására), ráadásul az üzeneteink megőrződnek a helyi mobiltelefon-adótoronyban, így könnyen leleplezhető a turpisság. Emellett nem ismervén minden adótorony azonosítóját, az újonnan létrehozott üzenetek egységesen az adott szolgáltató 9999-999 azonosítójú („telefonszámú”) adótornyát tartalmazzák a végső továbbító állomás bejegyzésnél, ezt pedig bármely vizsgálat egyszerűen kimutatja, s ennek módosítására csak a program átírásával nyílik lehetőség. A VC6Sample.exe elindítása után a kártyaolvasó rövid olvasási műveletét követően a következő ablaknak megfelelő kép tárul elénk, kijelezve az épp aktuális kártyainformációkat. Ha induláskor nincs behelyezve SIM kártya, akkor „Érvénytelen SIM kártya” üzenetet kapunk, vagy egyéb probléma esetén az
Scard.err-ben definiált egyéb magyar nyelvű hibaüzeneteket. A sorszám a SIM kártya hátoldalán szereplő sorszámot tartalmazza, amely 19 vagy 20 jegyű lehet, 19 jegy esetén az utolsó, 20. számjegy az „f” Igen gyakran nem írják rá azonban a SIM hátuljára az első négy jegyet, az mindig 89xx formátumú, ahol az xx az adott ország előhívója. Ez Magyarországnak a 36 A következő két jegy pedig a mobilszolgáltató körzetszáma (jelen esetben 70) A kártyatípus a SIM kártyán található szolgáltatóspecifikus üzenetsztring (ha támogatott, ha nem, akkor a program a sorozatszám alapján egy adatbázisból választ). A panel jobb oldalán a PIN állapotáról kaphatunk némi információt, hogy aktív-e és hogy még hány kísérletünk van a helyes PIN kód megadására. Figyelem, ha ez a számláló 0-ra kerül, az a kártya blokkolásához vezet! Ekkor 10 lehetőségünk van a PUK kód megadására, azonban ez már a programban nincs implementálva,
erre a célra használjunk egy mobiltelefont! 10 próbálkozás után a kártya tartalma végérvényesen elvész! Ha a „PIN aktív” jelölőnégyzetet megváltoztatjuk, a program megkísérli a változtatást a kártyán is végrehajtani. Ez csak abban az esetben sikerülhet, ha a „PIN ellenőrzés” felirat melletti mezőbe beírjuk a PIN kódot Ha nincs beírva semmi, semmi nem történik, 17 azonban ha a beírt kód hibás, eggyel csökken a PIN kód megadására szolgáló számláló értéke! Ugyanez történik akkor, ha a „PIN ellenőrzés” feliratú gombra kattintunk, ezzel a funkcióval tudjuk ugyanis feloldani a védett állományokat, melyek eléréséhez PIN kód szükséges. Az első lépés egy rádiótelefon esetében is az, hogy bekéri a PIN kódot, hacsak a kód, vagy az ellenőrzési folyamat előzetesen nem lett letiltva Ezt a lépést valósítja meg a „PIN ellenőrzés” Egy ellenőrzés egy teljes „session”-re érvényes, azaz amíg ki nem
vesszük a kártyát, nem kell többet újra megadnunk. A „PIN1” és „PIN2” rádiógombok értelemszerűen azt határozzák meg, hogy melyik PIN kódot kívánjuk ellenőrizni. Csak az ellenőrzésre vannak hatással, deaktiválni ugyanis csak az elsődleges PIN kódot lehet Az ablak bal oldalát szinte teljes egészében elfoglaló mező szolgál a kiválasztott tartalom megjelenítésére. A legfelső sorában a legördülő menü segítségével választhatjuk ki a témakört a „Saját számok”, az „SMS (Rövid szöveges üzenetek)” és a „Telefonszámok” közül. Bármelyiket is választjuk, annak megjelenítéséhez a tőle kissé jobbra elhelyezkedő „Beolvas” gombra kell kattintanunk Ha a SIM kártya PIN kódja aktív, akkor a sikeres művelethez előbb fel kell oldani a PIN kódot, különben hibajelzést kapunk. Ezt a már említett módon, a szövegmezőbe beírt kód után a „PIN ellenőrzés” gombbal tehetjük meg Ekkor rövid várakozás után
megjelennek a kért információk, a scrollbarral navigálhatunk a szövegen. A bal oldalon elsőként mindig az adott szám vagy üzenet sorszáma található 1-től a maximális értékig. A maximumérték kártyánként változó, általában elmondható, hogy a „Saját számok” témakör 3-5 bejegyzést tartalmazhat, az „SMS” általában 15-öt, míg a „Telefonszámok” 100-tól 250-ig elég széles skálán mozog. A „Saját számok” és a „Telefonszámok” a sorszám után tartalmazzák a nevet, majd a telefonszámot. A telefonszám tartalmazhatja a nemzetközi előhívót („+”), vagy a 3 másodperces várakozás jelet („-”, a mobiltelefonok általában a „□” jellel ábrázolják) is A név hosszúsága SIM kártyánként eltérő lehet. 18 Az „SMS (Rövid szöveges üzenetek)” témakör már kissé összetettebb. A sorszám után következő mező az üzenet típusát mutatja. Ez szabvány szerint öt féle lehet, de leggyakrabban csak
négy típusát használjuk: a) Olvasott üzenet Ez a leggyakoribb üzenettípus, mellyel egy SIM kártyán találkozhatunk. Mint a neve is utal rá, egy egykori Új üzenet elolvasott verziója, melyet nem töröltünk ki, hanem valamilyen okból megtartottunk b) Új üzenet Az új, még elolvasatlan üzenetek típusa ez, ha már megtekintettük, akkor Olvasott üzenet lesz belőle. c) Tárolt üzenet Ez az az üzenetfajta, amikor vagy saját magunk részére készítünk valamilyen bejegyzést, vagy egy megírt, de még valamilyen okból el nem küldött üzenetet tárolunk a kártyán. Bizonyos telefonok a „Kimenő üzenetek” címszónál mutatják meg az ilyen típusú üzeneteket. d) Elküldött üzenet Ez a legritkább típus, még nem találkoztam olyan mobiltelefonnal, hogy a megírt és el is küldött SMS-eket megőrizte volna a készülék. Ha mégis létezik ilyen, akkor azok az üzenetek alkotják ezt a típust. e) Törölt üzenet Ez a típusa azoknak az
üzenettárolásra alkalmas rekordoknak, melyek nem tartalmaznak érvényes üzenetet. Az érvényes szó alatt azt értem, hogy már kitörölt üzenetek maradványait találhatjuk itt, melyet az eljövendő új üzenetek majdan felülírnak Bizonyos esetekben lehetőség van a már kitörölt üzenetek olvasására, de az újabb SIM kártyák már üres hellyel töltik fel a kitörölt üzenetek helyét. A törölt üzenetek, ha nem deríthető ki a tartalmuk, akkor a „Törölt üzenet: Nem visszaállítható!” bejegyzést mutatnak, különben zárójelben az üzenet korábbi típusa szerepel, s innentől fogva minden a korábbi típusnak megfelelően folytatódik. (Lásd ott!) 19 A „Tárolt üzenetek” és az „Elküldött üzenetek”, tekintve, hogy saját magunk írtuk őket, csak az üzenet szövegét tartalmazzák, a kártya ugyanis nem jegyzi meg az elküldött telefonszámot. Az „Új üzenetek” és „Olvasott üzenetek” elsőként a küldő
telefonszámát, alfanumerikus esetben (telematic interworking) a küldő nevét tartalmazzák, amit egy jobbranyíl () követ. Ezután szögletes zárójelben ([]) szerepel a küldés pontos dátuma és időpontja, majd végül a szöveg. A szövegben az egyes vezérlőkaraktereket (CR, LF) a visszaper jellel () helyettesítettem, egyébként pedig ahol lehetett, magyarra konvertáltam a betűket. A „Szerkeszt” funkcióval a rekordok tartalmát módosíthatjuk. Amint rákattintunk egy új dialógusablak tűnik fel, kezdetben üresen. A föl-le nyilakkal kiválaszthatjuk vagy akár be is gépelhetjük a szerkesztőmezőbe a szerkeszteni kívánt bejegyzés sorszámát. Ezután a „Beolvas” gomb segítségével megjelenik a kívánt információ. A „Törölt” állapotjelző tájékoztat arról, hogy üres bejegyzést látunk-e, SMS esetén ilyenkor, ha az üzenet visszaállítható, akkor maga az üzenet is megjelenik, mint a példán is látható. A „Szám” a küldő
telefonszámát (vagy nevét) tartalmazza, a „Dátum” pedig a küldés idejét, s alattuk található az üzenet szövege. Tetszés szerint szerkeszthetjük mindhárom mezőt, sőt a „Törölt” állapotjelzőt is. Ha elégedettek vagyunk az eredménnyel, kattintsunk az „Elmentés” gombra, és a módosítások nyomban aktualizálódnak a kártyán is. Ezt rövid szintaktikai ellenőrzés előzi meg, az esetlegesen felmerülő hibáról visszajelzést kapunk Ha bezárjuk az ablakot, vagy a „Vége” gombra kattintunk, a program kilép a szerkesztőből és visszatérünk a fődialógusablakhoz. 20 Az „Újraolvas” gomb csupán a kártyainformációk frissítésre szolgál, a lista tartalmának frissítésére a „Beolvas” gomb szolgál. A programból kilépni a „Kilépés” gombra kattintva lehet 21 3. A felhasznált módszerek rövid ismertetése 3.1 Microsoft Visual Studio A Visual Studio egy átfogó programcsomag, mely számtalan komponenseinek
egyike a Visual Basic, a Visual Java és a Visual C++. Mióta a C programozási nyelv megszületett, az egész világot meghódította. Gyors és hatékony, ezért közkedvelt a programozók körében. A programnyelv objektum-orientált továbbfejlesztésének egy változatát alakította ki a Microsoft, a Visual C++ programozási nyelvet. A Visual C++ minden komoly, Windows alatt futó programokat készítő szoftverfejlesztő cégnél, mint munkaeszköz szerepel. Én a programjaimat az akkor még legújabbnak számító 6-os verzióval kezdtem fejleszteni, időközben megérkezett azonban a 7-es verzió is, amely .NET-ként is ismeretes A Microsoft Visual C++ nagyon sok könnyen emészthető példát tartalmaz, ezáltal is megkönnyítve a szoftverfejlesztést. Mindig az elérhető egyik legátfogóbb és legkifinomultabb szoftverfejlesztői környezet volt. Magas szintű programozási hatékonyságot és kényelmet nyújt, miközben változatos segédprogramokat is tartalmaz, melyek
szinte minden programozási stílushoz megfelelnek. A Visual C++ 6-os verziója az említett, már eddig is meggyőző vonásokat is felülmúlja. Az új tulajdonságoknak köszönhetően könnyebben tudunk kódot írni, fordítani, hibákat keresni; még több a támogatás az ActiveX és Internet technológiák terén; további adatbázis-fejlesztési lehetőségeket kapunk, valamint új alkalmazás-felépítési és felhasználói-felületi lehetőségeink vannak, mint például a Microsoft Internet Explorer 4 stílusú kontrollok A programfejlesztést hatékonyan segíti elő az alkalmazott varázsló-alapú megközelítés. Természetesen magát a forráskódot saját magunknak kell előállítani, a Visual C++ csak felépít egy vázat, amely egyszerűbbé teszi a dolgunkat. A ClassWizard segítségével csupán néhány kattintás segítségével változókat, függvényeket deklarálhatunk, üzenetkezelő függvényeket definiálhatunk és még sok más dolgot, majd egy újabb
kattintás után azonnal a szerkesztendő kódnál termünk, nekünk már csak az utasítások megadása a feladatunk. Az erőforrás-szerkesztő egy WYSIWYG (What You See Is What You Get) szerkesztő, melyben a kívánt kontrollok megfelelő helyre tologatásával és az egyes tulajdonságok beállításával rövid idő alatt megadható a felhasználói interfész. A két CD-nyi Súgó (Microsoft Developer Network) olyan tudásanyagot ölel át, melynek teljes elolvasása szinte lehetetlenség, ráadásul minden évben újabb kiegészítések (Platform SDK) jelennek meg. 22 3.2 Microsoft Foundation Classes A Microsoft Visual C++ számos különböző módozatot kínál fel Windows GUI (Graphical User Interface - a Windows grafikus felhasználói felülete) programok írására. Először is írhatunk GUI programokat C++-ban közvetlenül olyan függvények felhasználásával, amelyekkel az alapvető Win32 API szolgál, ami pedig része a Windows 9x és Windows NT operációs
rendszereknek. E megközelítéssel azonban rengeteg rutin kódsort kell begépelnünk még mielőtt az alkalmazásunkhoz tartozó feladatokra koncentrálhatnánk. Másodsorban írhatunk Windows GUI programokat C++-ban a Microsoft Foundation Classes (MFC) felhasználásával is. Az MFC az előre megírt osztályok és segédkódok hatalmas gyűjteményével rendelkezik, amelyek számos olyan szabványos Windows programozási feladatot kezelhetnek, mint például az ablakok létrehozása és az üzenetek feldolgozása. Használhatjuk az MFC-t arra is, hogy pillanatok alatt fejlett eszközökkel bővítsük a programjainkat, úgymint az eszköztárak, az elválasztott nézetek és az OLE támogatás. Valamint használhatjuk olyan ActiveX kontrolok létrehozására is, amelyek újrafelhasználható szoftverkomponensek és megjeleníthetők a Web böngészőkben és más konténer-alkalmazásokban is. Az MFC leegyszerűsítheti a GUI programjainkat és a programozási munkánkat
meglehetősen könnyebbé teheti. Vegyük figyelembe, hogy az MFC függvények belsőleg meghívják a Win32 API függvényeket, így az MFC „beburkolja” a Win32 API-t, s ezáltal magasabb szintű, hordozhatóbb programozási felülettel szolgál. Az MFC programokban szintén szabadon, közvetlenül hívhatunk Win32 API függvényeket, így az MFC használatával nem veszítünk azok képességeiből. Az MFC programok alapértelmezés szerint az ún. Document/View Architecture Support-ot használják, minek eredményeként az AppWizard különféle osztályokat generál a tároláshoz és a programunk adatainak megtekintéséhez, valamint kóddal szolgál az adatok lemezről történő olvasásához és arra történő íráshoz. 3.3 NMAKE A Microsoft Program Maintenance Utility (NMAKE) egy 32 bites segédprogram, melylyel projekteket fordíthatunk le parancssorból, ha azok a megfelelő formátumú, parancsokat definiáló leíró fájlt (makefile) tartalmazzák. A gsview32.exe
lefordításához szintén az NMAKE-et használtam, tekintve, hogy a gsview32 projekt ún. makefile alapú projekt A fordítandó makefile a gvwinvcmak nevű fájl volt. Ez elsőként minden fájltípusra a neki megfelelő fordítóalkalmazást hívja meg (.c, cpp fájlok esetén clexe stb), majd az így létrejövő tárgykódokat összeszerkesztő alkalmazást hívja meg (link.exe) A megváltoztatandó forráskód tanulmányozásának első lépése a makefile-ok végigböngészése volt annak céljából, hogy milyen szerkezeti sajátságok fedezhetők fel a programban. Később, szintén manuálisan, kellett módosítani a makefile-okat, kiegészítve az általam hozzáadott komponensekkel. Mivel a projekt makefile alapú, eleve így lett megtervezve, hogy a más fordítóprogramokkal való minél nagyobb kompatibilitást elérjék, s nincs mód bármiféle varázsló használatára. A program működésének megértése ilyen feltételek mellett mindenesetre számtalan új
tapasztalatot biztosított számomra a Win32 API használatában, hiszen a Visual Studio számtalan előnye mellett „elkényezteti” a programozókat. 23 3.4 Towitoko A Towitoko ChipDrive kártyaolvasók családja rendkívül kényelmes megoldás minden intelligens kártya alapú rendszer fejlesztése és használata szempontjából. Legyen az elektronikus fizetési eszköz, diákigazolvány, vagy a mobiltelefonok SIM kártyái, a chipkártya hosszú ideje a jelenkor és a multimédia iránt érdeklődő közösségek fő támaszává vált. Természetesen a chipkártyák nem igazán használhatók kártyaolvasók nélkül. Ezen eszközök révén kapcsolódnak az intelligens kártyák a személyi számítógépekhez, amelyek hatékony és biztonságos elektronikus összeköttetést létesítenek közöttük A folyamatosan bővülő hatalmas piac ellátásához a Towitoko olyan chipkártya terminálokat fejlesztett ki, amelyek alkalmazások széles körét támogatják. A
cég megbecsülést vívott ki magának az intelligens kártyák terén az alkalmazások pontos megvalósításával és képesek voltak egy innovatív technológiát a végfelhasználók elvárásainak megfelelően alkalmazni. A német Towitoko AG 12 év alatt vált a terület egyik vezető vállalatává. A Towitoko ChipDrive Micro a világ legkisebb kártyaolvasója volt 2000-ben, mindöszsze fél bankkártyányi mérete miatt. A Towitoko termékek egyszerű programozhatóságuk mellett a legolcsóbbak a piacon, akár már 20 euróért is találunk nekünk megfelelőt. (A képen lévő árak még DM-ban szerepelnek.) 3.5 ScardServer Számos különböző cég gyárt manapság intelligens kártyákat, kártyaolvasókat és meghajtóprogramokat. Szintén számos különböző saját szabványt fejlesztettek ki a gyártó cégek a kártyák kezelésére. Az ScardServer kifejlesztésének célja az volt, hogy 24 olyan könnyűvé tegyék, amennyire csak lehet az intelligens
kártyák és kártyaolvasók kezelésének saját alkalmazásainkba ágyazását. Az ScardServer a háttérben futó szerveralkalmazás a Windows 3.11, 95, 98, ME, NT, 2000 és XP operációs rendszereken. Az alkalmazások többféle protokollt felhasználva kommunikálhatnak a szerverrel: a) Scard interfész - SCARD.DLL, SCARD32DLL Az Scard interfész által kihasználható a teljes ScardServer szolgáltatás. A kliensoldali alkalmazásokban való implementációja rendkívül egyszerű, egyetlen DLLfüggvényhívást használhatunk mindenfajta eléréshez Az alkalmazásbeli eseménykezelés az ablakok szokásos üzeneteinek segítségével történik Az interfész elérhető mind 16, mind 32 bites verziók alatt a Windows 3.11, 95, 98, ME, NT, 2000 és XP operációs rendszereken. A DELPHI 1/2/3/4/5 nyelveket használva ráadásul még egyszerűbb a dolog, egy letölthető komponenst felhasználva. Ezt az interfészt pont az említett tulajdonságai miatt választottam, hogy az
intelligens kártya programozásában még nem járatos programozók is könnyen megismerhessék a benne rejlő lehetőségeket. b) PC/SC interfész Ezt az interfészt a PC/SC Workgroup (http://www.pcscworkgroupcom) készítette, a Windowsos változat mellett elkészült a Linux/Unix alatt futó verzió is. A PC/SC használatához Windows 9x/ME/NT alatt a PC/SC Base Components feltelepítése szükséges, a Windows 2000 és XP már tartalmazza a legutolsó verziót, a Windows 3.11 viszont nem támogatott A PC/SC interfész Microsoftos implementációjáról részletes leírás található a Microsoft Windows SDK-n. További információk és a fejlesztői levelezési listára való feliratkozási lehetőség a http://www.microsoftcom/smartcard internetcímen A telepítéshez szükséges állományok szintén itt találhatók vagy a Windows 98 Second Edition CD-ROM-on A Towitoko cég fejlesztése az a Unit for Delphi 2/3/4/5 komponens, amelyben a legtöbb PC/SC funkciót
megvalósították, hozzásegítve a Delphi programozókat, hogy ezt az interfészt használhassák. A MUSCLE (Movement for Using Smart Cards in a Linux Environment) projekt keretében szintén kidolgoztak egy PC/SC implementációt Linux/Unix alá. További információk és Linux driver a CHIPDRIVE intelligenskártya-olvasókhoz található a http://www.linuxnetcom weboldalon c) CTAPI interfész - CTAPIW16.DLL, CTAPIW32DLL A CT-API interfész kompatibilis a CT-API V1.1 (kiadta a Deutsche Telekom AG / PZ Telesec, GMD Forschungszentrum Informationstechnik GmbH, TÜV Informationstechnik GmbH és a TeleTrust Deutschland e.V) szabvánnyal és 16 bites és 32 bites verzióban is elérhető További információk a specifikációt illetően a http://www.tuevitde internetcímen találhatók Az utasításkészletet az MKT (Multifunktionale Kartenterminals für das Gesundheitswesen, kiadta: GMD Arbeitsgemeinschaft “Karten im Gesundheitswesen“) előírásainak megfelelően implementálták,
s az interfész az ScardServer lehetőségeinek nagyon kis hányadát használja ki. d) OCF interfész - GEN TWK.DLL Ennek az IBM által kifejlesztett interfésznek a segítségével a ChipDrive-ot Java alapú alkalmazásokban is használhatjuk. További információk az Open Card Framework (OCF) interfészről a http://www.opencardorg internetcímen találhatók 25 e) TDEV interfész - TDEV.DLL, TDEV32DLL A TDEV interfész csupán a Towitoko korábbi interfészének támogatása céljából létezik. Ajánlott az új Scard interfész használata az új fejlesztések teljes körű kihasználása érdekében 16 és 32 bites verziói léteznek Windows operációs rendszerek alá. 3.6 ETSI A European Telecommunications Standars Institute szabályozza az Európai rádiótelefon-szolgáltatások alapvető technikai részleteit. Többszáz szabvány, szabványonként olykor többszáz oldal jellemzi a területet, hiszen a legdinamikusabban fejlődő területek egyik a mobiltelefónia,
és a folyton fejlődő technológia újabbnál újabb felmerülő lehetőségeinek, problémáinak egységes kezelésére van szükség a szolgáltatók egymással való kompatibilitásának céljából. Az egyik ETSI szabvány, a GSM 02.17 határozza meg azt az elképzelést, hogy az MS (Mobile Station - a felhasználó készüléke) célszerűen két egységre bontandó, a cserélhető SIM (Subscriber Identity Module) egységre, amely minden hálózati azonosítással öszszefüggő részt tartalmaz, és az ME (Mobile Equipment) egységre, amely az MS fentiektől eltérő része, és a szokásos funkciókkal, szolgáltatásokkal rendelkezik. A GSM 02.17 szabvány a SIM kártyák két fajtáját engedélyezi: - IC card SIM (nagy, bankkártya méretű) - plug-in SIM (kis alakú) Szintén a 02.17 szabvány definiálja, hogy a SIM kártya „élete” két fázisra bontható fel (miután kijött a gyárból): - administrative management fázis (a szolgáltató tulajdonában van)
- GSM network operation fázis (a felhasználó tulajdonában van) A GSM 11.11 szabvány határozza meg az ME és a SIM kapcsolatát és a SIM belső szerkezeti felépítését a GSM network operation fázisban való megfelelő működés garantálása céljából. A szabvány csupán logikai szempontok szerinti implementációt takar, és nem tartalmaz technológiaspecifikus megvalósítási részleteket Ez a szabvány volt a leghasznosabb a szakdolgozat elkészülte szempontjából. Szintén szükségem volt többek között az ISO 7816-4 szabvány (Interindustry commands for interchange) mellett a GSM 03.40 (Digital cellular telecommunications system (Phase 2); Technical realization of the Short Message Service (SMS) Point-to26 Point (PP)), a GSM 04.11 (Digital cellular telecommunications system (Phase 2); Pointto-Point (PP) Short Message Service (SMS) support on mobile radio interface) és a GSM 03.38 (Digital cellular telecommunications system (Phase 2+); Alphabets and
language-specific information) szabványokra. 3.7 CSP A cryptographic service provider (CSP) egy független szoftvermodul, amely kriptográfiai algoritmusokat és szolgáltatásokat tartalmaz, amelyeket a CryptoAPI-ba integráltak. A CryptoAPI (Microsoft Cryptographic API) a Microsoft kriptográfiai API-ja, amely lehetővé teszi az alkalmazásfejlesztők számára, hogy autentikációt, kódoló függvényeket és titkosító algoritmusokat adhassanak a Win32-alapú alkalmazásaikhoz. A fejlesztők anélkül használhatják a CryptoAPI funkciókat, hogy bármit is tudnának az adott implementációról, nagyon hasonlóan ahhoz, mikor egy grafikus library-t használva szintén semmit nem lehet tudni az adott grafikus hardverről. A legalapvetőbb esetben egy CSP egy dynamic-link library-ből (DLL) és egy signature fájlból áll. Számos CSP a Microsoft Win32 application programming interface-t (API) kiszolgáló program, melyeket a Win32 service control manager vezérel. A CSP-knek
van egy úgynevezett családja (CSP family), a CSP-k egy egyedi csoportja, melyek ugyanazt az adatformátumot használják és működésükben is nagyon hasonlóak egymáshoz. Nem csak az különböztet meg két CSP family-t, hogy eltérő algoritmust (pl. a RC2 block cipher algoritmust) használ, lehet, hogy az eltérő helykitöltő módszerek (padding schemes), kulcshosszok (keys lengths) vagy alapbeállítások (default modes) által válnak különbözővé. A CryptoAPI-t úgy tervezték, hogy minden egyes CSP típus egy különböző családot reprezentáljon. A CSP-k jellemzője a neve (CSP name), amely egy karaktersorozat. Ha a Microsoft hitelesítette CSP-t szeretnénk használni, akkor ennek a névnek pontosan meg kell egyezni az Export Compliance Certificate-ben (ECC) szereplő CSP névvel. Szintén a CSP-k jellemző tulajdonsága a típusuk (CSP type). Ha egy alkalmazás egy adott CSP-hez hozzákapcsolódik, minden CrytoAPI funkció alapbeállításként úgy fog
működni, ahogy az adott CSP típusának megfelelő családban be van állítva. 27 II. Fejlesztői dokumentáció 4. A feladat részletes specifikációja A korábbiakban már említésre került, hogy a témabejelentőn vállalt feladat egy nyilvános forráskódú program oly módú átdolgozása volt, hogy csak bizonyos, intelligens kártyák általi azonosítás után lehessen azt lefuttatni. Ebben a fejezetben kiemelten foglalkozom a biztonság kérdéskörrel, valamint felvázolom, hogy milyen követelményeknek kell megfelelni egy működő alkalmazásnak. A probléma elemzése során előnyben részesítem a gyakorlati megközelítést, tekintve, hogy a kitűzött cél egy általános séma felépítése volt. A Fejlesztői dokumentáció részletes anyaga terjedelmi okokból csak a CD-mellékleten található verzióban szerepel, a nyomtatott verzióban csak némi bevezetés található. 4.1 A GSM SIM kártyák A GSM SIM kártya tulajdonképpen egy olyan Java alapú
processzorkártya, melyen egy, az ISO és az ETSI szabványok által specifikált feltételeknek megfelelő alkalmazás található. Az intelligens kártyák fizikai felépítése az ISO/IEC 7816 part 1-3 (Asynchronous smartcard information) szabványok által definiált. Néhány jellemző tulajdonságot összefoglalok itt, a teljes verzió elolvasásához azonban fel kell keresni az ISO honlapját a http://www.isoch internetcímen Ezek után következik a kártya logikai felépítése. A Java Card API objektum orientált szemléletű, a külvilág számára látható metódusok pedig argumentumként APDU-kat (Application Data Unit) kapnak. Ezeket az APDU-kat az ISO/IEC 7816-4 (Interindustry commands for interchange) által definiált módon használják. Erről egy elég részletes összefoglaló olvasható Bo Lavare honlapján, azon belül pedig a következő címen: http://www.geocitiescom/ResearchTriangle/Lab/1578/iso78164htm Fontos megjegyezni, hogy míg az ISO szabvány a teljes
intelligens kártya témakört szabályozza, addig az ETSI kifejezetten a GSM SIM kártyákra tartalmaz előírásokat. E kettősség megjelenik magában az implementációban is, miszerint némi eltérés tapasztalható a két szabvány között, és ilyen esetekben mindig az ETSI szabvány által mondottak érvényesülnek. Ezért is került a feladat részletes specifikációjába maga az intelligens kártyák definíciója, mivel az eredeti célkitűzések között nem konkrétan SIM kártya, hanem intelligens kártya szerepel. A feladat megadása is tartalmazza az intelligens kártya kifejezést, ezért szükséges azt itt definiálni. És ezért kerültek a felhasznált módszerek részletes leírásába az ETSI szabványok, mert a módszerek már a SIM kártyára vonatkoznak. Mindemellett mostanában észlelhető egyfajta tendencia, amely megpróbálja levetkőzni az ISO szabvány által definiált korlátokat, időszerűvé vált ugyanis egy új szabvány kidolgozása, mivel a
technika túlhaladta a korábbit. Az ISO 7816 szabvány fontosabb pontjai a következők: a) ISO7816-1 Standard (fizikai paraméterek) - Minimális érintkezési felület - Az érintkezők elhelyezkedése 28 b) ISO7816-2 Standard (méret és az érintkezők helyzete) - Az érintkezők hozzárendelése - Az érintkezők pozíciója c) ISO7816-3 Standard (elektromos jelek és átviteli protokollok) - Az elektromos jelek leírása - Feszültség és a feszültségértékek - Az IC kártyák működési mechanizmusa - Answer to Reset (a kártya tulajdonságainak meghatározása) d) ISO7816-4 Standard (értelmezett parancsok) Ezzel a témakörrel részletesen foglalkozom a későbbiekben. 4.11 Az intelligens kártyák fizikai paraméterei (ISO7816-1) Az ISO 7816-1 szabvány rengeteg fizikai paramétert definiál, de én csak a legérdekesebbeket idézném föl az elkövetkezőkben: - Ultraibolya sugárzás A szokásos szintet meg nem haladó mértékű UV sugárzás nem
károsíthatja a kártyát, a kártyagyártó joga eldönteni, hogy alkalmaz-e bármely védelmet a szokásos UV sugárzási szintet meghaladó sugárzás esetére. - Röntgensugárzás A kártya bármely oldalát egyszerre maximum 0.1 Gy dózist meg nem haladó, éves összesítésben 70 és 140 Kv (kumulatív dózis/év) közötti erősségű röntgensugárzás esetén a kártyának működőképesnek kell maradni. - Az érintkezők felszíne Az érintkezők és a kártya más részének felszíne közötti eltérés nem haladhatja meg a 0.1 mm-t - Mechanikai hatások (a kártyán és az érintkezőkön) A kártya maradjon sértetlen és mind a felszíni, mind a belső alkotóelemek álljanak ellen a normális napi használat, tárolás és egyéb alkalmazások során fellépő erőhatásoknak. Az érintkezési felület károsodás nélkül ki kell bírjon akkora nyomást, melyet egy, a felületnek 1.5 N erővel nekinyomódó 15 mm átmérőjű acélgolyó fejt ki -
Elektromos ellenállás Két érintkező közötti ellenállás nem haladhatja meg a 0.5 Ohmot 50 és 300 µA közötti áramerősség esetén - Mágneses mező A kártyában található chipet nem károsíthatja egy 79500 Atr/m erősséget meg nem haladó statikus mágneses mező. - Statikus elektromosság A kártya ellen kell álljon egy 1500 V feszültségű 100 pF kapacitású elektromos kisülésnek 1500 Ohm ellenállással. 29 - A kártya maximális hajlékonysága (Az alábbi adatok a bankkártya-méretű kártyára vonatkoznak.) A deformáció nagysága (m) a kártya hosszabbik oldala esetében 2 cm, a rövidebbik oldaláén 1 cm. Percenként 30 hajlítgatás gyakoriság esetén a kártyának tökéletesen kell működni, valamint 1000 hajlítgatás után sem repedhet el. - Minimális érintkezési felület Minden érintkező felülete a 8 közül legalább az alábbi méretű legyen. - Az érintkezők elhelyezkedése Az intelligens kártyán a chip két helyen
lehetséges, bár az AFNOR pozíciót nem minden olvasó támogatja, mivel az csak a már meglévő mágnescsíkos-chipes kártyákkal való kompatibilitás miatt maradt meg. Bizonyos kártyákon mindkét érintkezőn át elérhető a mikrochip (dupla kivezetés). 4.12 Az intelligens kártyák mérete és az érintkezők helyzete (ISO7816-2) A számos szabály közül szintén csak néhányat emelnék ki: - Az érintkezők hozzárendelése C1 Vcc = 5 V C2 Reset C3 Clock 30 C4 RFU C5 GND C6 Vpp C7 I/O C8 RFU - Az érintkezők pozíciója AFNOR A (mm) B (mm) C (mm) D (mm) C1 17.87 19.87 16.69 18.39 C2 17.87 19.87 14.15 15.85 C3 17.87 19.87 11.61 13.31 C4 17.87 19.87 9.07 10.77 C5 10.25 12.25 16.69 18.39 C6 10.25 12.25 14.15 15.85 C7 10.25 12.25 11.61 13.31 C8 10.25 12.25 9.07 10.77 ISO7816 A (mm) B (mm) C (mm) D (mm) C1 10.25 12.25 19.23 20.93 C2 10.25 12.25 21.77 23.47 C3 10.25 12.25 24.31 26.01 C4 10.25 12.25
26.85 28.55 C5 17.87 19.87 19.23 20.93 C6 17.87 19.87 21.77 23.47 C7 17.87 19.87 24.31 26.01 C8 17.87 19.87 26.85 28.55 4.13 Az intelligens kártyák elektromos jelei és az átviteli protokollok (ISO7816-3) - Az elektromos jelek leírása I/O: A kártya belsejében található integrált áramkör (IC) soros átvitelre alkalmas Input/Output csatlakozása VPP : Programozó feszültség bemenet (opcionális, kártyafüggő) GND : Föld (nullfeszültség) CLK : Órajel vagy időzítő jel (opcionális, kártyafüggő) RST : Vagy önmagában használatos(a reset jel az olvasótól érkezik) vagy egy belső reset-vezérlő áramkörrel kombinálva (opcionális, kártyafüggő). Ha a belső reset implementált, akkor folyamatos VCC feszültséget igényel. 31 VCC : Üzemfeszültség (opcionális, kártyafüggő) RFU: További fejlesztésre fenntartva (Reserved for Future Use) - A maradék két érintkező tulajdonságait az azt használó alkalmazás határozza
meg. - Feszültség és a feszültségértékek A szabvány nagyrészt az elektromos jellemzők megengedett minimális és maximális értékeit definiálja. A pontos számadatok felsorolását nem érzem indokoltnak, az megtekinthető az eredeti szövegben. A szabványban a következő rövidítések találhatók: Vih: Vil: Vcc: Vpp: Voh: Vol: tr: tf: Iih: Iil: Icc: Ipp: Ioh: Iol: Cin: Cout: - Magas bemeneti feszültség (High level input voltage) Alacsony bemeneti feszültség (Low level input voltage) Üzemfeszültség a VCC-n (Power supply voltage at VCC) Programozó feszültség a VPP-n (Programming voltage at VPP) Magas kimeneti feszültség (High level output voltage) Alacsony kimeneti feszültség (Low level output voltage) Felfutási idő az amplitúdó 10 %-ától 90 %-áig (Rise time between 10% and 90% of signal amplitude) Leesési idő az amplitúdó 10 %-ától 90 %-áig (Fall time between 90% and 10% of signal amplitude) Magas bemeneti áram (High level input current)
Alacsony bementi áram (Low level input current) Üzemáram a VCC-n (Supply current at VCC) Programozó áram a VPP-n (Programming current at VPP) Magas kimeneti áram (High level output current) Alacsony kimeneti áram (Low level output current) Bemeneti kapacitás (Input capacitance) Kimeneti kapacitás (Output capacitance) Az IC kártyák működési mechanizmusa A szabvány az alábbi működési mechanizmust határoz meg minden érintkezővel rendelkező IC kártya számára. Az olvasó eszköz és a kártya közötti információcsere az alábbi részműveletek egymásután következésével történik: 1. csatlakozás és az érintkezőket aktiválja az olvasó 2. kártya reset 3. a kártya válaszol a resetre (answer to reset) 4. információcsere a kártya és az olvasó között 5. az érintkezőket deaktiválja az olvasó Az érintkezők mindig deaktivált állapotban vannak, amíg meg nem történik a csatlakozás, elkerülendő, hogy a kártya behelyezés közben
meghibásodjon. Az olvasó a kártyának reset jelet küld, amire a kártyának válaszolni kell egy adott időn belül. Ha ez nem történik meg, az érintkezőket deaktiválni kell Az answer to reset (ATR) nagyon fontos lépés, ugyanis a kártya ekkor közli az olvasóval és azon keresztül az azt kezelő rendszerrel (ScardServer) a legalapvetőbb fizikai és logikai jellemzőit. 32 A deaktiválás akkor történik, ha valamilyen fizikai hiba lép fel, vagy az olvasó azt észleli, hogy a kártyát eltávolítják. - Answer to Reset Két féle átviteli mód lehetséges: 1. Aszinkron átvitel: Ebben a típusú átviteli módban a karakterek küldése az I/O vonalon aszinkron félduplex módon történik. Minden karakter egy 8 bites bájtnak felel meg 2. Szinkron átvitel: Ebben az átviteli módban bitsorozatok küldése történik az I/O vonalon fél-duplex módon, órajeles szinkronizációval a CLK vonalon. Az ATR logikai struktúrája a következő: TS : Initial character
T0 : Format character TAi : Interface character TBi : Interface character TCi : Interface character TDi : Interface character T1, . , TK : Historical characters (max 15) TCK : Check character Az „initial character” határozza meg az őt követő adatok formátumát. Az „interface character”-ek a chip fizikai paramétereit határozzák meg és az alkalmazott átviteli protokoll logikai karakterisztikáját. A „historical character”-ek általános információkat közvetítenek, mint például a kártya gyártóját, a chip típusát, a ROM jellemzőit stb. Ezeket az információkat az ScardServer eltárolja, így bármikor lekérdezhetjük. A alkalmazott adatátviteli protokoll a GSM SIM kártyák esetében mindig a T0 (aszinkron fél-duplex karakter-átviteli protokoll), ez egyébként a TDi bájtokból olvasható ki. 4.14 Az intelligens kártyák által értelmezett parancsok (ISO7816-4) Az ISO 7816 4. része rendkívül terjedelmes, ezért itt sem térek ki minden
intelligens kártyával kapcsolatos tényre, csupán a GSM SIM kártyákhoz szükséges információkat közlöm. Az ISO7816-4 már sokkal inkább logikai szerveződéssel foglalkozik, mint az előzőek. Mielőtt részletes ismertetésbe kezdenék, szót kell ejteni az alkalmazott fogalmakról és a felhasznált rövidítésekről. 4.141 Definíciók adatelem: A legkisebb olyan bithalmaz, amelyre egyértelműen hivatkozni lehet. adat objektum: Az olvasó interfész szintjén megjelenő információ, amely címkéből, hosszból és egy értékből tevődik össze. Az ISO/IEC 7816 által használt adat objektum-ok BEP-TLV, COMPACT-TLV és SIMPLE-TLV adat objektumok lehetnek dedicated file (DF): Olyan fájl, amely file control paramétereket, vezérlő- és egyéb, alkönyvtárhoz hasonló információkat tárol. Mind DF-nek, mind EF-nek lehet őse 33 DF név: Karaktersztring, amely egyértelműen azonosítja az adott dedicated file-t a kártyán. master file: A kötelezően egyedi
dedicated file, amely a fájlrendszer gyökerét alkotja. szülő file (ős): Olyan dedicated file, amely közvetlenül az adott fájl felett áll a hierarchiában. elérési út: Fájl azonosítókból konkatenációval előálló sorozat, amely ha a master filelal kezdődik, akkor abszolút elérési útról beszélünk. elementary file (EF): Olyan adatelemek vagy rekordok együttese, amelyek egyazon fájl azonosító alá tartoznak. Nem lehet más fájlok őse belső elementary file: Olyan elementary file, amelyet a kártya belső működése során tart karban és adatokat tárol benne. külső elementary file: Olyan elementary file, amelyet nem a kártya tart karban. file control paraméterek: Egy fájl logikai, strukturális és biztonsági attribútumai. fájl azonosító: Egy 2-bájtos bináris érték, mely egy fájl meghatározására szolgál. file management data: Bármely információ egy fájlról, kivéve a file control paraméterek-et, pl. érvényességi idő, dátum,
alkalmazás, címke stb jelszó: Adat, amelynek a felhasználó részéről történő megadását egy alkalmazás kérheti. kibocsátó: Olyan szervezet, amelynek joga van létrehozni dedicated file-okat a kártyán. Answer-to-Reset fájl: Olyan elementary file, amely a kártya működési tulajdonságairól tudósít. command-response pár: Két összetartozó üzenet, mely egy parancsból és az őt követő válaszból áll. üzenet: Olyan karaktersorozat, amelyet az olvasó küld a kártya felé, vagy fogad tőle. rekord: Olyan karaktersorozat, amelyet a kártya egybefüggőként kezel, és hivatkozni lehet rá a rekord számával vagy a rekord azonosítójával. rekord azonosító: Egy rekordhoz tartozó érték, amelyet hivatkozásként lehet a rekordhoz használni. Több rekordhoz is tartozhat egy azonosító egy elementary file-on belül rekord szám: Szekvenciálisan minden rekordhoz tartozó egyedi azonosító, amely egy elementary file-on belül egyértelműen azonosítja.
4.142 Rövidítések APDU Application protocol data unit ATR Answer to reset CLA Class byte DIR Directory DF Dedicated file EF Elementary file FCI File control information 34 FCP File control parameter FMD File management data INS Instruction byte MF Master file P1-P2 Parameter bytes PTS Protocl type selection RFU Reserved for future use SM Secure messaging SW1-SW2 Status bytes TLV Tag length value TPDU Transmission protocol data unit 4.143 Jelölések 0-9 és A-F Tizenhatos számrendszerbeli számok (B1) B1 értéke B1||B2 B1 bájt és B2 bájt konkatenációja # Szám 4.144 Adatszerkezetek Az ISO/IEC 7816 a fájlok két kategóriáját különbözteti meg: - Dedicated file (DF) - Elementary file (EF) Emellett a DF-ek hierarchiába szerveződnek, amelynek csúcsán az MF (master file) áll. Az MF jelenléte kötelező. Ezen kívül más DF-ek is létezhetnek Két fajta EF-et ismerünk: - belső EF: Az EF-et a kártya tartja
karban, s a működéshez szükséges, valamint egyéb vezérlő információkat tárol. - külső EF: Nem a kártya által karbantartott EF, s kizárólag a külvilág által használt információkat tartalmaz. A fájlokra különféle módokon hivatkozhatunk. Ha nincs kiválasztva a kívánt fájl, akkor: - Hivatkozhatunk a fájl azonosítóra: Minden fájl elérhető a 2 bájtos azonosítójával. Az MF fenntartott azonosítója a „3F00”. Az „FFFF” érték RFU, s fenntartott a „3FFF” is. Minden EF és DF azonosítója különböző egy adott DF-en belül - Hivatkozhatunk az elérési útra: Minden fájl elérhető az elérési út által, amely fájl azonosítók konkatenációjából áll. Az elérési út az MF-fel vagy az aktuális DF-fel kezdődik és a kívánt fájl azonosítójával ér véget. Egy fájlszerkezethez illő módon 35 minden azonosítót megelőz az őse. Ha nem ismert az aktuális DF neve, akkor a fenntartott „3FFF”-et használhatjuk
helyette. - Hivatkozhatunk a rövid EF azonosítóra: Minden EF-re hivatkozhatunk az ő 5 bites rövid azonosítójával (1-30-ig). A 0 érték az aktuális EF rövid neve A rövid EF azonosító nem használható elérési útban, valamint fájl azonosító helyett, pl. a SELECT FILE parancsban. - Hivatkozhatunk a DF nevére: Minden DF elérhető az ő 1-16 bájt méretű nevével. Minden DF névnek egyedinek kell lenni egy kártyán. A fájlokat szerkezetük szerint csoportosíthatjuk: - Transzparens struktúra: szekvenciális adatot tartalmaz - Rekord struktúra: különálló, külön hivatkozható rekordok összessége Rekordok esetében további két jellemzőt érdemes tudni, hogy a rekord mérete: fix vagy változó méretű, és hogy a rekord szerveződése: lineáris vagy ciklikus szerkezetű. A kártya legalább az alábbi adatszerkezetek egyikét kell, hogy támogassa: - Transzparens EF - Lineáris, fix méretű rekord EF - Lineáris, változó méretű rekord
EF - Ciklikus, fix méretű rekord EF Minden rekordra egy rekord EF-en belül hivatkozhatunk a rekord azonosítójával vagy a rekord számával. Ezek előjel nélküli 8 bites egész számok „01”-től „FE”-ig A „00” fenntartott érték, az „FF” pedig RFU. A rekord azonosítójára történő hivatkozás egy rekordmutató segítségével valósul meg, ha a rekord számára hivatkozunk, ahhoz nincs szükség a rekordmutatóra. A mutatót számos művelet megváltoztatja, pl. SELECT FILE - Hivatkozás rekord azonosítóval: Ha a rekord egy SIMPLE-TLV (tag-length-value) adat objektum, akkor a rekord azonosítója az első bájtja az adat objektumnak. Ez természetesen megegyezhet két külön bejegyzés esetén egy EF-en belül is. Ettől függetlenül bizonyos esetekhez, pl. kereséshez megfelelhet Minden alkalommal, amikor rekord azonosítóra hivatkozunk, azt is meg kell adni, hogy az első, az utolsó előfordulást keressük, vagy a rekordmutatóhoz képest az
előző vagy következő előfordulást. Csupán a ciklikus rekordoknál okozhat gondot az értelmezés, itt a legutoljára létrehozott rekordbejegyzés az első bejegyzés, az utolsó előtti a második stb Ha nincs érvényes rekord kiválasztva, akkor következő előfordulás és az előző előfordulás megegyeznek az első és az utolsó előfordulással. A „00” speciális rekord azonosító, egyaránt lehet az első, az utolsó, a következő vagy az előző előfordulás a rekordmutatótól függetlenül. - Hivatkozás rekord számmal: Minden rekord EF-en belül a rekord számok egyediek. Lineáris struktúra esetén a rekordszámok folyamatosan nőnek, a #1 a legelőször létrehozott rekord. Ciklikus szerkezetű rekord esetén a számozás fordított (az utolsó rekord készült legrégebben). A „00” speciális rekordszám, az épp aktuális rekordot (rekordmutató) jelenti. Minden bináris (transzparens) EF-en belül hivatkozhatunk az egyes adatelemekre úgy,
hogy megadunk egy eltolási értéket (offset), pl. a READ BINARY utasításban Ez az 36 eltolási érték egy előjel nélküli egész szám, 8 vagy 15 bites, az alkalmazott utasítástól függően. A 0 az első adatelemet jelenti, 1 a következő elemet stb Ha a kártyán másként nem implementált, egy adatelem egy bájtnyi méretű Elképzelhető, hogy egy rekord EF is támogatja az adatelemeinek elérését, ekkor azonban az alkalmazásnak ismernie kell a rekordbejegyzések szerkezetét, tekintve, hogy egy rekord bizonyos elemei a vezérlőinformációkat tartalmazzák. Épp ezért nem tanácsos a használata ismeretlen struktúrák esetén. 4.145 Biztonság Többféle biztonsági eljárást támogathatnak az intelligens kártyák: - Kóddal védett: PIN kód megadása, ez a leggyakoribb - Kulccsal védett: A GSM SIM kártyák pl. így azonosítják magukat a szolgáltatóközpont felé, rendelkeznek egy titkos kulccsal, amit csak a központ ismer -
üzenetazonosítással (secure messaging): ezek a kulcspárok elvén működő módszerek A kód megadásával három féle biztonsági elv léphet működésbe: - Globális biztonsági státusz: Tekintve, hogy a MF automatikusan kiválasztásra kerül, amint behelyeztük a kártyát, valamint minden fájlnak őse, ezért ha a teljes kártyát le szeretnénk védeni, elég a MF-et levédeni. - Fájl-specifikus biztonsági státusz: Az elve nagyon hasonló az előzőhöz, azzal a kivétellel, hogy itt bizonyos DF-ek kerülnek levédésre, az MF-hez viszont hozzáférhetünk. - Utasítás-specifikus státusz: Itt bizonyos utasítások végrehajtásának feltétele a megfelelő kód vagy kulcs megadása. 4.146 APDU-k Az utasításokat mindig az olvasó küldi a kártya felé. A parancsok 5 bájtos fejrészből, majd az azt követő adatokból állnak. Az utasításfejrész formátuma: CLA, INS, A1, A2, L (Az A1 - address1, A2 - address2, L - length részeket gyakran emlegetik
paraméterekként, s ennek megfelelően a nevük P1, P2, P3.) - CLA: az utasítás osztálya (instruction class). Az „FF” érték a protokoll-kiválasztásra (PTS) fenntartva. - INS: az utasítás kódja (instruction code) az osztályban. Az utasításkód érvényes, ha a legkisebb bit értéke 0 és a felső fél bájt sem 6, sem 9. - P1, P2: paraméterek az utasításhoz - P3: az adatblokk bájtjainak száma (n, ahol D1, . , Dn az adatok), amely adatblokk az adott utasítás során kerül küldésre. Hogy az adatblokk bemenő, vagy kimenő adat, azt mindig az utasításkód határozza meg, s ettől függ, hogy az utasításfejrészt követően további adatok küldése történik-e. Pl a P3=5 kimenő adat esetén azt jelenti, hogy a P3 bájtot nem követi más adat, viszont a várt adatfolyam hossza 5 bájt 37 Itt kell megjegyeznem, hogy az ISO7816-4 másféle parancsszerkezetet engedélyez, az iménti, a SIM kártyák által használt ennek egy egyszerűsített
változata. Ugyanis a szerkezet: „CLA INS P1 P2 [Lc field] [Data field] [Le field]” típusú szerkezet, amely megegyezik az előzővel, csak az Lc csak a megadott adatblokk (Data) hosszát tartalmazza, az Le mező tartalmazza a várt adatblokk hosszát. Azonban Lc=0 esetén az Lc és a Data elhagyható, ha Le=0, akkor Le hagyható el, ha mindkettő 0, akkor az egyiket ki kell tenni, a SIM kártyák nem használnak olyat, hogy egyik sem 0, ezért alkalmazható az egyszerűsítés. Egyébként minden parancsoldali RFU bit vagy bájt értéke mindig 0, kivéve, ha ezt valahol másként definiálják. Vizsgáljuk külön-külön az egyes bájtok értékét: a) Az utasítás osztálya (CLA byte) Az ISO szabvány számos variációt engedélyez, ezek teljes megértéséhez viszont számos olyan fogalmat is definiálni kellene, ami nem tartozik a GSM SIM kártyák kategóriájába, így itt csupán annyit közlök, hogy SIM kártyák esetében a CLA bájt értéke mindig „A0” (no
secure messaging, no logical channels). b) Az utasítás kódja (INS byte) Ami semmiképpen nem lehet: b8 b7 b6 b5 b4 b3 b2 b1 Jelentése x x x x x x x 1 páratlan 0 1 1 0 x x x x 6X 1 0 0 1 x x x x 9X Bizonyos értékek nem minden kártyán vannak implementálva az alább felsorolt utasításkódok közül. A GSM SIM kártyákról bővebben az ETSI részben foglalkozom Kód Utasítás neve 0E ERASE BINARY 20 VERIFY 70 MANAGE CHANNEL 82 EXTERNAL AUTHENTICATE 84 GET CHALLENGE 88 INTERNAL AUTHENTICATE A4 SELECT FILE B0 READ BINARY B2 READ RECORD(S) C0 GET RESPONSE C2 ENVELOPE 38 CA GET DATA D0 WRITE BINARY D2 WRITE RECORD D6 UPDATE BINARY DA PUT DATA DC UPDATE DATA E2 APPEND RECORD c) A paraméterek (P1-P2 bytes) A paraméter bájtok bármilyen értéket felvehetnek, ha valamelyik paraméter nem használt, akkor annak a „00” értéket kell tartalmaznia. d) Adatmező (Dafa field bytes) Ha az adatmező egy TLV adat
objektum, akkor az adatmező első bájtja egy címke (tag), második bájtja a hossz (length) és ezt követi a hossznak megfelelő számú érték (value). Ha a hossz „FF”, akkor az őt követő két bájt határozza meg a hosszt Itt még számos további definíciót tartalmaz a szabvány, a SIM kártyák azonban nem használják ezeket, csak a már korábban is említetteket. 4.147 Válasz APDU A válasz APDU szerkezete a következő: „[Data field] SW1 SW2” Figyelem! Az ScardServer, megkönnyítendő a dolgunkat az „SW1 SW2 [Data field]” formátumot használja, így a kártya válaszában számunkra érdekes „status byte”-ok (SW1, SW2) mindig az első két bájton találhatók. Az SW1=$6x vagy $9x, kivéve $60; az SW2 bármi lehet. Az SW1, SW2 a kártya állapotát mutatja az utasítás végrehajtása után Normális befejeződés esetén az SW1-SW2=$90-$00 (a „-” jel kötőjelként és nem kivonásként szerepel!). Az ISO7816-3 definiál bizonyos hardveres
hibaüzeneteket Ha az SW1 felső fél bájtja $6, az SW1 alkalmazástól független jelentéssel bír, méghozzá: $6E: A kártya nem támogatja az utasításosztályt $6D: Az utasításkód nem megfelelő vagy nem implementált $6B: Az utasítás paramétere hibás $67: Az utasításhossz nem megfelelő $6F: Egyéb hiba történt A többi érték alkalmazásfüggő. Az utasításfejrész ellenőrzése ebben a sorrendben történik, így pl. a $67 egyben azt is jelenti, hogy a kártya egyébként támogatja az adott kódú utasítást. Az ISO nem határoz meg SW1=$9X értékű, vagy bármely SW2 értékű hibaüzenetet, azt az alkalmazások határozzák meg. 39 Az ISO7816-4 által definiált alkalmazásspecifikus hibaüzenetek Normál befejeződés: SW1-SW2 Jelentése 9000 Minden rendben 61XX SW2 tartalmazza a válaszban lévő, még visszamaradó bájtok számát Az SW1 $61 értéke helyett megengedett a $9F is. Figyelmeztető jelzések: SW1-SW2 Jelentése 62XX Nem
felejtő memória tartalma nem változott 63XX Nem felejtő memória tartalma megváltozott Végrehajtási hibák: SW1-SW2 64XX Jelentése SW2=0 esetén a nem felejtő memória tartalma nem változott különben RFU 65XX Nem felejtő memória tartalma megváltozott 66XX Biztonsági funkcióknak fenntartva Ellenőrzési hibák: SW1-SW2 Jelentése 6700 Hibás hossz 68XX A CLA osztály nem támogatott 69XX Az utasítás nincs engedélyezve 6AXX Hibás paraméter (P1-P2) 6B00 Hibás paraméter (P1-P2) 6CXX Hibás hossz (P3), a helyes érték SW2 6D00 Az utasításkód nincs implementálva 6E00 A CLA osztály nem támogatott 6F00 Egyéb hiba Az előzőekben sok helyen az SW2 helyén XX szerepel, ezekre térek ki most. SW1=62: SW2 00 Jelentése Nincs információ 40 81 A küldött adat hibás lehet 82 A fájl vége megszakította az olvasást 83 A fájl nem választható ki 84 Az FCI hibás SW1=63: SW2 Jelentése 00 Nincs információ 81 Fájl
feltöltve CX Az X (0-15) számláló megváltozott SW1=65: SW2 Jelentése 00 Nincs információ 81 Memória hiba SW1=68: SW2 Jelentése 00 Nincs információ 81 Logical channel nem támogatott 82 Secure messaging nem támogatott SW1=69: SW2 Jelentése 00 Nincs információ 81 A fájlszerkezettel nem kompatíbilis utasítás 82 Biztonsági státusz nem kielégítő 83 Autentikációs folyamat leállítva 84 Hivatkozott adat nem létezik 85 Használati feltételek nem kielégítők 86 Az utasításhoz ki kell választani egy EF-et 87 Elvárt SM adatok hiányoznak 88 SM adatok nem megfelelőek 41 SW1=6A: SW2 4.2 Jelentése 00 Nincs információ 80 Az adatmezőben található paraméter hibás 81 Funkció nem támogatott 82 A fájl nem létezik 83 A rekord nem létezik 84 Nincs elég memóriahely a fájlban vagy rekordban 85 P3 nem megfelelő a TLV struktúrához 86 A P1 és/vagy P2 nem megfelelő 87 A P3 értéke nem megfelelő
az adott P1 és P2 mellett 88 Hivatkozott adat nem létezik Biztonsági megfontolások Ha egy programot autentikációval látunk el, annak az a feladata, hogy megbízhatóan azonosítsa az illetékes és kiszűrje az illetéktelen személyeket. A tudomány mai szintjén az azonosítás már kellőképp megbízható lehet egyes biometrikus adatok felhasználásával, ezek alkalmazásának költsége azonban igen magas. Így ésszerű kompromisszum, hogy minél alacsonyabb költségen az előzőeknél csak kissé alacsonyabb hatékonyságú eszközöket használjunk fel. Ily módon ésszerű választás az intelligens kártyák alkalmazása Itt is nagyon széles a választék mind az ár, mind a szolgáltatások szempontjából, s ezek a tényezők erősen befolyásolhatják egy adott típusú kártya elterjedését. A fenti tényezők miatt és számos más okból a SIM kártyák használata mellett döntöttem Mint korábban említettem már, a támadási lehetőségek két
csoportba sorolhatók: fizikai és logikai támadásra aszerint, hogy alacsony szinten, a hardver szintjén, vagy magasabb szinten, szoftverszinten támadják a rendszert. A támadások szintén csoportosíthatók a megtámadott eszköz alapján, ezáltal a kártya, a kártyaolvasó terminál, az operációs rendszer, az autentikációs adatállomány vagy maga az alkalmazás ellen irányuló támadást különböztetünk meg. Ezeket vizsgálom meg részletesen Az alábbi magyarázatok részletes megértése végett ajánlott az adott témakört együttvizsgálni a hozzávaló forráskóddal, melyeket a dolgozat III. fejezetében találunk Létezik a támadások másfajta csoportosítása is. Például a neves amerikai biztonságtechnikai szakértő, Bruce Schneier a támadó személyét vizsgálja, a személyes motivációkat és a támadónak a rendszerben betöltött szerepét, szemben az általam alkalmazott támadott hardvereszközök vizsgálatával. Ő a manapság Amerikában
közkedvelt módszert alkalmazva, egyfajta pszichológiai megközelítést választ. Megvizsgálja milyen motiváló tényezők lépnek fel, melyek ezek elhárítási módozatai stb. Én a magam nevében ehhez csak annyit tudok hozzátenni, hogy gyakorlatilag a kétféle megközelítés azonos eredményre vezet. Hiszen a támadó személye valamilyen hardvereszközt támad meg, esetleg az általam „logikai szint”-nek titulált módszereket alkalmazva. Másik részről, minden 42 megtámadott hardver mögött ott az elkövető is, akinek személyes indítékai vannak, így visszajutottunk a támadók pszichológiájához. Bruce Schneier cikke megtalálható magyar nyelven a Biztostű szerverén a Hallgatói munkáknál Lécz Pál fordításában a http://biztostu.hu/tovabbi anyagok/hallgatoi munkak/Pal Lecz/sctpdf címen Érdemes megfontolni azokat a gondolatokat, melyeket a cikk, mint tanulságok levonása közöl. Ezek szerint különösen hátrányos az adattulajdonos
számára, ha a kártyát a rajta lévő adataival egy másik személy kezébe kell adnia. Esetünkben ez nem áll fenn, ugyanis kártyatulajdonos és az adattulajdonos egyazon személy Ettől eltérni csak úgynevezett „szerepcsere” esetén lehet, amikor eltulajdonítják a kártyát, de ezt a problémát részletesen elemzem a későbbiekben A kártya másik legnagyobb hátránya az, hogy nem képes önálló kommunikációra, így különösen sebezhető a terminál támadásaival szemben. Esetünkben ez sem játszik szerepet, mivel a terminál tulajdonosa egyben a kártya tulajdonosa is. Fontos tanulság az említett cikkben az is, hogy a résztvevő szereplők csökkentésével fokozatosan növekszik a biztonság is. A mi esetünkben a minimális, két szereplő (szoftver előállító és felhasználó) található. Mindezeket figyelembe véve, mint a későbbiekben látni fogjuk, az alkalmazott módszer kijátszásának lehetősége csak olyan esetekben merülhet fel, melyek
a hozzávaló eszközök vagy a szükséges munkaidő miatt jóval drágábbak, mint amibe egy átlagos szoftver kerül. 4.21 Az alkalmazás ellen irányuló támadások Minden egyes támadási kísérlet tulajdonképpen ebbe a kategóriába lenne sorolható, ugyanis minden támadás célja a program védelmének kijátszása. Ezen túlmenően a támadások a rendszer valamelyik láncszemét (ha úgy tetszik a leggyengébb láncszemet) veszik célba, és azon keresztül kísérelnek meg egy, az alkalmazás ellen irányuló támadást. Az ilyen jellegű próbálkozásokat külön témakörbe soroltam, csak az egyéb kísérletek kerültek ebbe a szakaszba, amelyek közül sok az emberi tényező hibáiból ered 4.211 Fizikai szint Ilyen témakör, ha belegondolunk, nem létezik, tekintve, hogy az alkalmazás nem más, mint a háttértárolókon lévő mágneses jelek vagy a memóriában lévő töltések összessége. Hiszen nem szükséges ilyen alacsony szinten kezelni ezeket,
megvannak erre a fejlettebb lehetőségek Amiért mégis létrehoztam ezt a témakört, az az, hogy bizonyos próbálkozások, pl. a program fájljainak átírása közel áll a „szétszedem és megváltoztatom” stílusú gondolkodáshoz, amely egyébként a hardveres szintre jellemző Az egyes kategóriák a következők: a) memóriaátírás Valós támadási lehetőség, ha ismerjük annak a változónak a memóriabeli címét, amely a beolvasott kártya azonosítóit tartalmazza. Ezzel azonban még mindig két probléma van: meg kell szereznünk egy érvényes kártya azonosítóit (ez a kevésbé nehéz), és az autentikációs mechanizmust közvetlenül az ellenőrzés előtt kell megállítani, de közvetlenül a beolvasás után. Ha ebben a pillanatban sikerül átírni a memóriacímek tartalmát, a védelmet kijátszottuk Az iménti mód eléggé nehezen, de megvalósítható, mert folyamatos memóriafigyeléssel kideríthető az említett memóriacím. Persze
megtehetnénk, hogy a memóriában kódolva tároljuk az információkat, de nem sokat nyernénk vele a következő lehetőség miatt 43 b) crack file Úgyis valószínűbb, hogy a hackernek nem a memóriában, hanem a fájlban sikerül hatástalanítani a védelmet azáltal, hogy az összehasonlítás után a „nem egyezés” esetén módosítja a memóriacímet az ugrásnál. Így ugyanoda ugrik a vezérlés az alkalmazásban, mint „egyezés” esetén Ezt kellő assembly ismeret fejében és a program visszakövetésével lehet megoldani Ez ellen nincs védelem, csupán nehezíthetjük a dolgot azzal, hogy az összehasonlítást többször megismételjük az alkalmazás során. 4.212 Logikai szint A kártya elleni logikai támadás. Ide tartoznak a nem alacsony szintű, a nem hardverszerű támadások Egyes támadási módok ugyan hardver szinten történnek, de az elkerülésükhöz magasabb szintű mechanizmusok kötődnek, s így ezeket ehhez a szinthez soroltam Az
egyes kategóriák a következők: a) nincs kártya Az alkalmazás intelligens kártyán alapuló autentikációval foglalkozik, így a legegyszerűbb támadási mód az, ha kártyát nem birtokló illetéktelen személy elindítja az alkalmazást. Amint azt a felhasználói dokumentáció is tartalmazza, a szoftver addig nem indul el, amíg nincs megfelelő kártyánk. Sőt, egy kártya, jelen esetben bármilyen kártya az autentikációs mechanizmus elindulásának is feltétele b) idegen kártya Ebben a szakaszban egyenértékű, hogy az idegen kártya GSM SIM kártya-e vagy sem. Az autentikációs mechanizmus érzékeli, hogy rendelkezésre áll egy kártya, azonban már az első lépésnél elutasítja azt, mivel a kártya sorozatszáma (ha nem SIM kártya, akkor a sorozatszám definíció szerint 0) nem szerepel az adatbázisban. c) lopott kártya Az autentikációs mechanizmus első lépése sikeres, mert az egyébként érvényes kártya sorozatszáma az adatbázisban van.
Következő lépésként az IMSI kódot olvasnánk ki a kártyáról, ehhez azonban, ha a PIN kód nincs letiltva a kártyán, szükség van a PIN kódra. A PIN kódot pedig, remélhetőleg nem a kártya mellett egy kis cetlin tároljuk, csak a tulajdonos ismeri Így a második lépés elutasítja a kártyát Ha a PIN kódot letiltottuk kényelmi okokból, akkor sajnos egy eltulajdonított kártyával a védelem kijátszható. Létezik azonban több megoldás is ennek elkerülésére Első megoldás a PIN2 kód használata, mert az nem tiltható le. Az alkalmazásnak nincs más teendője, mint egy esetleges letiltott PIN kód esetén a PIN2 kód bekérése. Ehhez persze a PIN2 kódot szintén tárolni kellene az adatbázisban. Második megoldás a PIN kód bekapcsolása, majd újra kikapcsolása. Ehhez semmilyen újabb adatállomány nem szükséges, ráadásul csak a PIN kódot kell fejben tartanunk, mivel a PIN állapotának megváltoztatásához erre van szükség Amiért egyik
lehetőséget sem alkalmaztam, annak oka az, hogy mindenki felelőssége teljes tudatában deaktiválja a PIN kódot, pontosan azért, hogy később ne kérje tőle semmilyen alkalmazás, mert pl. képtelen megjegyezni stb Így létezik egy kényelmes, ámbátor kevésbé biztonságos megoldás d) kölcsönadott kártya Kényelmes megoldás nyújt, ha valaki kölcsönkap egy érvényes kártyát. Ekkor ő valóban illetéktelen személy, viszont a kártya kölcsönadója addig nem használhatja az 44 alkalmazást. Ez értelmes kompromisszumnak tűnik, tekintve, hogy a felhasználó kilétének ellenőrzésére semmilyen módszer nem áll rendelkezésre a PIN kódok használatán kívül e) egyéb módszerek Mivel az autentikáció addig nem lép tovább, amíg érvényes kártyát nem talál, nincs jelentősége, hogy a felhasználó milyen billentyűkombinációkat üt le, a folyamat nem megszakítható, nem különválasztható a célalkalmazástól, a processz „megölése” a
teljes alkalmazás terminálását eredményezi, ugyanakkor nem marad vissza semmilyen tempfile, vagy bármilyen árulkodó nyom. 4.22 A kártya ellen irányuló támadások Ide azok a közvetlenül a kártya ellen irányuló támadási csoportok tartoznak, amelyeknek például közvetlenül egy „hamis” kártya létrehozásával próbálják a védelmet kiiktatni vagy egy érvényes kártyát illetéktelenül felhasználni. Tekintve, hogy processzorkártyáról van szó, a kártya elleni támadások jóval nehezebbek, mint egy egyszerű memóriakártya esetén. Nem különböztettem meg logikai szint és fizikai szint témaköröket, azokat együtt tárgyalom. Annyit tennék hozzá még, hogy a fizikai támadás a kártya ellen nagyrészt a legbonyolultabb esetek közé tartozik. A kártya fizikai támadásának több módja is van, attól függően milyen megközelítést alkalmazunk, míg a tisztán logikai támadási módok kizárhatók A felhasznált eszközök számos
különböző variációt tesznek lehetővé, de én csak azokat különböztettem meg, amelyek elviekben különböznek egymástól. Nem tisztán logikai módszer például, ha a kártyát az I/O portjain keresztül a fizikai specifikációnak megfelelő jelekkel gerjesztjük. A kártya belsejére következtethetünk a visszaadott outputok tartalmából, illetve az input és az output között eltelt időből. Ekkor ugyanis csak feltérképeztük a kártyát, szükségünk van továbbra a fizikai módszerekre ahhoz, hogy az adatokhoz hozzáférjünk. A következő témakörök tartoznak ide: a) saját kártya módosítása Tegyük fel, hogy rendelkezünk egy érvényes kártya adataival. Például egy barátunk rendelkezésünkre bocsátotta a saját kártyáját, de mivel nem akar lemondani a program használatáról, így nekünk saját kártya szükséges. Ehhez nincs is más teendőnk, mint a rendelkezésünkre álló eszközökkel egy már meglévő kártyánk sorszámát és
IMSI kódját módosítani. Mint már korábban említettem egy SIM kártya életszakasza három részre osztható: gyártás, adminisztratív fázis, felhasználás. A kártya a felhasználóhoz a „felhasználás” fázisában kerül, ez azt jelenti, hogy ő az említett két adatot csak olvashatja Ha valaki esetleg a szolgáltató alkalmazásában áll, akkor is csak az adminisztrációs fázisban találkozik a kártyával, és csak az IMSI módosítására van lehetősége. Csak a kártyagyártó képes arra, hogy módosítsa egy kártya sorozatszámát, de ez a gyártási folyamat részeként kerül végrehajtásra, utólag ez sem módosítható. Ez a terv tehát logikai szinten megvalósíthatatlan. Fizikai szinten elvileg megvalósítható, bár véleményem szerint egy kártya belsejének megváltoztatása olyannyira drága művelet, hogy nem igazán jöhet számításba. A kártya fizikai védelme azonban a kártyagyártó feladata. 45 b) kártya másolása Ez a
módszer annyiban különbözik az előzőtől, hogy itt nem kölcsönvett, hanem lopott kártyát kísérelnek meg másolni. Egyrészt meg kell birkózni az írás nehézségeivel, másrészt problémák merülnek fel az olvasással is A kártya sorozatszáma ugyan nyilvános adat, az IMSI kiolvasása azonban PIN kódhoz kötött, így arra mindenképpen szükség van. Fizikai szinten a feladat elvileg megvalósítható, a kártya fizikai védelme azonban a kártyagyártó feladata, és lehet, hogy a tárolt adatok még titkosítva is vannak. c) PIN kód megszerzése Az előző pont esetén válik szükségessé, vagy ha csupán fel kívánunk használni egy talált kártyát. A PIN kód nem definiált helyen található a SIM kártyán, implementációja kártyagyártó-függően van megoldva Ez még nehezebbé teszi a feladatot, hiszen még a file azonosítója sem ismert, ráadásul olyan belső fájlban van tárolva, ami akár a külvilág számára elérhetetlen külön
memóriaegységben is lehet. A PIN kód védelmének megoldása a kártyagyártó feladata. d) szimuláció Erre akkor kerülhet sor, ha a szabványok ismeretében elkészítünk egy olyan hardvert, ami minden tekintetben SIM kártyaként viselkedik a kártyaolvasó számára. Ilyen megvalósítás elképzelhető, akár egy számítógép segítségével is szimulálhatjuk a kártyát, csak a megfelelő feszültségértékek és áramerősségek átalakítása szükséges, de ehhez is legalább rendelkeznünk kell egy érvényes kártya adataival, hogy azt szimulálhassuk. 4.23 A terminál ellen irányuló támadások Ide azok az esetek tartoznak, amelyek a kártyaolvasóval tévesztik meg az alkalmazást. Itt szintén nem választottam külön a logikai és fizikai szintet az esetek kis száma miatt. A következő témakörök tartoznak ide: a) módosítjuk a kártyaolvasót Ez fizikai szinten történő beavatkozás. Megtehetjük, hogy részben módosítjuk a kártyaolvasót, vagy
egészében újat is építhetünk Az Interneten többféle olvasó kapcsolási rajza is megtalálható, a legegyszerűbb a Dumbmouse soros portra köthető olvasó, melyhez még meghajtóprogramot is lehet letölteni Azt hiszem fölösleges megemlíteni, hogy technikailag nincs semmi akadálya egy olyan olvasó megépítésének, amely nekünk tetszőleges kártyaadatokat küld vissza, sőt, ha igazán ügyesek vagyunk, még kártyára sincs szükség (lásd következő pont). Előfordulhat, hogy nincs mód a kártyaolvasó módosítására (pl. egy üzletben található olvasó esetén) Ilyenkor megvalósítható, hogy akár néhány perc alatt is sikerül egy speciális hardvereszközt az olvasóterminált a soros porttal összekötő vezetékre csatlakoztatnunk, amely módosítja a vezetéken áramló információt. b) szimuláció Fizikai szint. Egy hardvereszközzel elhitetjük a soros porttal, hogy valódi kártyaolvasó található rajta Ezt akár egy másik számítógép is
megteheti sima soros porton keresztüli kommunikációval (nullmodem kábel). Gondot okozhat azonban a kártyaolvasót vezérlő driver, tanácsos azt is módosítani. c) driverek módosítása A legegyszerűbb logikai szintű módosítás az itt felsoroltak közül, tekintve, hogy a fizikai módosítás gyakran egyben a driver átírását is jelenti. 46 Írunk egy olyan meghajtóprogramot, amely nem létező eszközt szimulál. Számtalan ilyen létezik, pl. FakeCD ami által a merevlemez egy alkönyvtárját a számítógép CD lemezként érzékeli, vagy ISOMaster ami egy .iso formátumú fájlt a merevlemezen virtuális CD-ROM-ként kezel 4.24 Az operációs rendszer ellen irányuló támadások Az operációs rendszer jellegéből adódóan itt csak logikai szinten történő támadásokról beszélhetünk. A következő témakörök tartoznak ide: a) saját operációs rendszer Nem túlságosan valószínű, de elvileg lehetséges a Windows 9X operációs rendszer oly módon
történő módosítása, esetleg egy teljesen saját, de Windows kompatibilis operációs rendszer létrehozása, hogy az a megfelelő kártyaadatokat módosítva közölje az alkalmazásunkkal. b) üzenetek lehallgatása Sokkal valószínűbb azonban a Windows belső üzeneteinek lehallgatása. Az ScardServer is lehallgatható üzenetekkel kommunikál az alkalmazásokkal. Ha az alkalmazásunk titkosított formátumú üzeneteket is használ, egy megfelelően agyafúrt, üzeneteket naplózó alkalmazás segítségével a rendszer akkor is kijátszható. 4.25 Az autentikációs állomány ellen irányuló támadások Az autentikációs állomány tartalmazza az érvényes kártyaazonosítókat. Leginkább valamely változtatástól védett helyen lenne a legjobb elhelyezni az Interneten, vagy más hálózaton, hogy a felhasználói szoftverek autentikáció céljából bármikor hozzáférhetnének. Ebben az esetben még kódolni sem kellene, azonban ha a szoftver nem léphet online
módon kapcsolatba az adott szerverrel, hanem más módon (pl. mailben) terjesztett a jogosult kártyaadatokat tartalmazó fájl, akkor a kódolatlan verziót egyszerű lenne kicserélni Az első esetben egy terjedelmes adatbázis áll rendelkezésre, amelyben minden érvényes kártya adatai szerepelnek, a második esetben viszont célszerűbb csak az adott felhasználó adatait tartalmazó fájlt készíteni. Bár már vannak biztató jelek (az Internet egyre nagyobb hazai térhódítása) és ráerőltetett példák is (A Microsoft cég WindowsXP rendszerének kényszerű aktivációja), úgy gondolom attól még messze állunk, hogy bármely program elindításakor ne legyen gond az Internetes azonosítás, beleértve az igen drága telefonos percdíjakat is. A következő témakörök tartoznak ide: a) a fájl módosítása Hagyományosan fizikai szintű támadási módszer. A fájl, ha jól védett szerveren található, akkor módosítás ellen a szerver biztonságosságának
megfelelő mértékig védett. Ha a programmal együtt a merevlemezen található meg, akkor ugyan könnyedén módosítható, viszont a kódolás feltörése nélkül semmit sem érünk el a módosítással. b) a fájl kódolásának feltörése A kódolást a Windows CryptoAPI-ja végzi. Nem ismeri a jelszót még a felhasználó sem, ez számára is megnehezíti a feltörést. Ugyancsak nem ismert sem a kódolási algoritmus, sem az, hogy a kártyaadatokat a fájl milyen formátumban tartalmazza. 47 A CryptoAPI minden, az API működéséhez szükséges fájlt 512 bites RSA algoritmussal kódol, úgyhogy onnan sem könnyű a jelszót kinyerni. Habár az autentikációs mechanizmusnak ismerni kell a jelszót, ezért ezt a futtatható állomány tartalmazza is, azonban azt szintén kódolva tartalmazza, és a kódolt információ helye nem ismert. Összességében elmondható, hogy bármilyen információt megfejteni csak a program nyomkövetésével lehet. Fontos azonban, hogy ha
sikerül is kideríteni a kódoláshoz használt jelszót, az a jelszó csak az adott alkalmazás futtatására alkalmas, más alkalmazások, melyek erre az autentikációs mechanizmust épülnek, más jelszót használnak. Sőt, ha nem nyilvános adatbázisban tároljuk a kártyainformációkat, akkor megoldható az is, hogy a felhasználó egyedi autentikációs fájlját egyedi jelszóval is kódolják. Ezzel az is megelőzhető, hogy az adott szoftver más példányai által használt jelszót sikerüljön kideríteni egyetlen példány feltörésével 48 5. A felhasznált módszerek részletes leírása A Felhasználói dokumentációban leírt módszerek közül néhány témakör bővebb kifejtést igényel. Néhány témakör már eleve közismert, pl a C++ programozási nyelv, ezért nem szándékoztam ismertetni magát a nyelvet, vannak azonban olyan témakörök is, melyek kevésbé ismertek, részletes ismertetésük azonban több kötetes könyveket igényelne.
Ezeknél a témaköröknél csak az általam használt, előnyös tulajdonságokat emeltem ki, vagy épp csak megindokoltam a módszer használatát, esetleg azokat az információkat írtam le, amelyek a program logikájának megértéséhez fontosnak véltem. Minden témakörnél jeleztem, hogy az adott témakör iránt érdeklődő olvasó hol talál részletes információkat az adott témakörről, emellett az Irodalomjegyzékben is említek több elolvasásra érdemes anyagot. A Fejlesztői dokumentáció részletes anyaga terjedelmi okokból csak a CD-mellékleten található verzióban szerepel, a nyomtatott verzióban csak némi bevezetés található. 5.1 A Microsoft Visual C++ 6 és a Microsoft Foundation Classes (bővebben: Michael J. Young - Visual C++ 6 Mesteri szinten) Talán a legjobb referencia a Visual C++ számára önmaga, hiszen az eggyel korábbi, az 5-ös verzióval hozták létre a 6-ost is. De nézzük miként is működik! Egy a Visual C++ által
létrehozott teljesen új projekt két konfigurációval rendelkezik alapbeállításként: a Win32 Debug és a Win32 Release. A Debug a program hibakereső verziójának generálására, a Release a program végső, optimalizált verziójának generálására alkalmas. Természetesen létrehozhatunk új konfigurációkat, vagy a meglévőket is módosíthatjuk. Általánosságban elmondható, hogy a Debug verzió által generált futtatható állomány mérete a Release verzió által generáltnak többszöröse, míg sebessége sokszor csak törtrésze az eredetinek. Köszönhető ez a temérdek „breakpoint” információnak, másrészt a debug library, amit a „statically linked library” opció esetén a fordító a programhoz hozzáfordít („shared DLL” opció esetén nem) több mint tízszeres méretnövekedést is eredményezhet. Ezen felül az optimalizálás személyes tapasztalataim szerint már semmit, vagy csak 1-2 kilobájtot csökkent a exe fájl méretén Az
AppWizard által generált forrásfájlok elegendőek egy funkcionális program felépítéséhez, azaz a forrásfájlok AppWizard-dal történő generálása után rögtön egy lefordítható és futtatható forráskód áll rendelkezésünkre. Természetesen azon kívül, hogy az így kapott program megjeleníti egy ablak kereteit, általában mást nem tesz. A fejlesztés e szakaszában számos újabb varázslót, különféle Visual C++ fejlesztési eszközt használhatunk fel ahhoz, hogy az alkalmazásunkat megfelelő tulajdonságokkal bővítsük ki. Egy MFC-t támogató projekt létrehozásakor az AppWizard több dologra rákérdez, ezek egyike, hogy egydokumentumos felületű (SDI) alkalmazást készítünk (mint pl. a Paintbrush, ahol egyszerre egy aktív dokumentum lehet nyitva), vagy többdokumentumos felületű (MDI) alkalmazást (pl. Word) Egy SDI alkalmazás négy osztályt tartalmaz: dokumentumosztály (CDocument), nézetosztály (CView), fő keretablak-osztály
(CFrameWnd) és az alkalmazásosztály (CWinApp), ahol az osztályok nevei után feltüntettem, hogy mely MFC osztályból származnak. Kicsit más kategória, de működésében nagyon hasonló az SDI alkalmazásokhoz a dialógusalapú alkalmazás, csak itt a négy osztály helyett kettő jön létre. Nincs szükség ugyanis fő keretablak-osztályra, ehelyett jön létre a dialógusosztály (CDialog leszármazottja), amely a korlátozott grafikai funkciók miatt magába foglalja a nézetosztályt és egyéb indokok alapján a dokumentumosztályt. Egy dialógusablak általában szabványos dialóguselemekből tevődik össze, ame49 lyekre az MFC saját megjelenítő függvénnyel rendelkezik. Ezért nincs szükség a nézetosztályra Megkönnyíti a dolgunkat, hogy a Visual C++ varázslók a generált kódot megjegyzésekkel látják el, amint azt a példákban látni is fogjuk Fontos „világnézeti” probléma, hogy amikor megvizsgálunk egy MFC alkalmazást, nem találunk
„main” függvényt, de még „WinMain”-t sem. Hogyan működik hát egy ilyen alkalmazás, hol adódik át a vezérlés? Egy MFC program a vezérlést csak relatíve kis időre kapja meg. Amikor egy „main” függvényt elindítunk, ott a vezérlés teljes mértékben átadódik, minden más processz a háttérbe szorul, általában fel is függesztődnek Erre nincs lehetőség akkor, amikor egy teljes grafikus multitasking operációs rendszer működik a háttérben, gyakorlatilag a rendszer beszüntetne minden általa nyújtott kényelmi szolgáltatást. Tehát az MFC programunkat úgy kell megírnunk, hogy támogassa ezt az elképzelést, és időnként adja vissza a vezérlést az operációs rendszernek. Nincs is igazából ebben semmi nehézség, például miután kirajzoltunk a képernyőre, visszaadjuk a vezérlést, egy időzítő pedig másodpercenként 25-ször lefuttatja a megadott függvényt, amely helyenként újrarajzoltatja a képernyőt. A felhasználó
biztosan nem fogja észrevenni a különbséget Visszatérve az automatikusan generált osztályokra, a program elődleges feladatai e négy osztály között kerülnek felosztásra, az AppWizard minden egyes osztályhoz külön forrásfájlokat hoz létre. Alapértelmezés szerint mind az osztályok, mind pedig az azokhoz tartozó forrásfájlok neveit a projekt nevéből származtatja, bár ezek módosíthatók. Például egy „Proba” nevű projekt esetén alapbeállításként a létrejövő fájlok és osztályok nevei: CProba, CProbaDoc, CProbaView és CMainFrame (ez nem változott). A Proba dokumentumosztályát CProbaDoc-nak nevezzük, és az MFC CDocument osztályából származik. A CProbaDoc fejlécfájlja a ProbaDoch, az implementációs fájl pedig a ProbaDoccpp nevet kapja A dokumentumosztály felelős a program adatainak eltárolásáért, valamint azok lemezről történő beolvasásáért és arra történő kiírásáért is A Proba nézetosztályát CProbaView-nak
nevezzük és az MFC CView osztályából származik. A CProbaView fejlécfájlja a ProbaViewh, az implementációs fájlja pedig a CProbaView.cpp nevet kapja A nézetosztály felelős a program adatainak a megjelenítéséért a képernyőn, nyomtatón vagy más eszközön és a felhasználói inputok feldolgozásáért Ez az osztály kezeli azt a nézetablakot, amely a program adatainak a képernyőn történő megjelenítésére használatos. A Proba fő keretablak-osztályát CMainFrame-nek nevezzük és az MFC CFrameWnd osztályából származik. A CMainFrame fejlécfájlja a MainFrmh, az implementációs fájlja a MainFrm.cpp nevet kapja Ez az osztály kezeli a fő programablakot, amely egy olyan keretablak (FrameWnd példány), amely tartalmaz egy ablakkeretet, egy címsort, egy menüsort és egy rendszermenüt. A keretablak tartalmazza a „Minimize”, a „Maximize” és a „Close” gombokat is és néha más olyan felhasználói felületi elemeket is, mint például egy
eszköztárat vagy egy állapotsort. A nézetablak, amelyet a nézetosztály kezel, a főablak ezen felületi elemeken belüli üres részét veszi birtokba, s ezt nevezzük a főablak kliensterületének is A nézetablak nem rendelkezik vizuális elemekkel, kivéve azokat a szövegeket és grafikákat, amelyeket a nézetosztály önmaga megjelenít. A nézetablak a főablak gyermeke, ami többek között azt jelenti, hogy mindig a főablak felett kerül megjelenítésre ezen ablak kliensterületének határain belül. Végezetül az alkalmazásosztály a CProbaApp nevet kapja, és az MFC CWinApp osztályából származik. A CProbaApp fejlécfájlja a Probah, az implementációs fájlja a Proba.cpp nevet kapja Az alkalmazásosztály kezeli a programot, mint egészet, azaz ő 50 hajtja végre az összes olyan feladatot, amely nem esik a másik három osztály egyikének hatáskörébe sem, ilyenek például a program inicializálása és a program végső „tisztogatásának”
végrehajtása. Minden MFC programnak pontosan egy példányt kell létrehoznia egy CWinApp-ból származó osztályból A négy fő osztály egymással egymás nyilvános tagfüggvényeinek meghívásával és üzenetek küldésével kommunikál és cserél adatot. Az AppWizard és a Developer Studio számos forrás- és beállítási fájlt hoz létre a négy fő osztályhoz tartozó forrásfájlok mellett. A főbb kiegészítő fájlok a következők: - Resource.h: Konstans definíciókat tartalmaz a program erőforrásaihoz Ezt a fájlt a Developer Studio erőforrás-szerkesztője tartja karban, és közvetve az összes fő .cpp fájl és a fő erőforrás-definíciós fájl (Proba.rc) is tartalmazza - StdAfx.cpp és StdAfxh: Az előrefordított fejlécfájlok generálására használatos - Proba.clw: A ClassWizard által használatos információkat tárolja - Proba.dsp: A Proba projektfájlja, amely az összes a projekthez tartozó beállítást és egyéb információt
tárolja. - Proba.dsw: A Proba projekt munkaterület-fájlja, amely információkat tárol a projekt munkaterületéről. Egy projekt-munkaterület egy vagy több egyedi projektet kezel A Proba projekt Developer Studio-ban történő megnyitásához ezt a fájlt kell kiválasztani. - Proba.rc: A fő erőforrás-definíciós fájl a programhoz, amely definiálja a gyorsbillentyű-táblázatot, az About dialógusablakot, a menüt, a sztringtáblázatot és a program verzióinformációit Ezt a fájlt a Developer Studio erőforrás-szerkesztője tartja karban, nem szabad közvetlenül javítanunk, és a Microsoft erőforrás-szerkesztője (RC.EXE) dolgozza fel, amikor a program lefordításra kerül - esProba.ico: A program fő ikonja Eleinte ez a fájl a szabványos MFC ikont tárolja, azonban átszerkeszthetjük a Developer Studio grafikus szerkesztőjével Ez az ikon kerül megjelenítésre a Proba ablak bal felső sarkában, a Windows tálcán és számos egyéb helyen. A
Probarc tartalmaz egy ICON kifejezést, amelynek eredményeként az erőforrás szerkesztő behelyezi ezt az ikont a program erőforrásai közé - esProbaDoc.ico: A dokumentum ikon A Proba program nem jeleníti meg ezt az ikont, a dokumentum ikonok MDI programokban kerülnek megjelenítésre. - esProba.rc2: Ez a fájl szolgál arra, hogy manuálisan definiáljunk programerőforrásokat, azaz hogy anélkül definiáljuk őket, hogy a Developer Studio által szolgáltatott interaktív erőforrás szerkesztőket használnánk. Eleinte nem tartalmaz semmilyen definíciót sem. Ha magunk akarunk egy erőforrást definiálni, akkor a definícióját ebbe a fájlba írhatjuk be Ezt a fájlt a fő erőforrásfájl (Probarc) szerkeszti be egy #include kifejezésen keresztül. Ezen fájlok mellett a Developer Studio a következő, különböző típusú információk tárolására használatos fájlokat hozza létre: Proba.aps, Probancb, Probaopt és Probaplg Az AppWizard generál egy
ReadMe.txt elnevezésű fájlt is, amely jellemzi azon fájlok nagy részét, amelyeket az AppWizard a programunkhoz generál. Az AppWizard által generált fájlok halmaza azoktól a programtulajdonságoktól függ, amelyeket mi választottunk ki a program generálásakor. 51 Az AppWizard által generált, imént felsorolt fájlok abban a projekt mappában kerülnek elhelyezésre, amelyet mi határoztunk meg a program forrásfájljainak generálásakor, valamint e projekt mappán belül a es almappában. A felsorolt fájlok között nem szerepelnek azok a kimeneti fájlok, amelyek a program lefordításakor keletkeznek (például a .obj, a res és a exe fájlok) Mint ahogyan azt korábban említettem, a kimeneti fájlok a projekt mappa Debug vagy a Release almappájában kerülnek elhelyezésre. A program működésének lépései Ha MS-DOS-os vagy Unix-os programozáshoz szoktunk, vagy még ha jártasak is vagyunk a konvencionális Windows GUI programozásban, akkor is
meglepődhetünk azon, hogy miként is működik a program - hol kapja meg először a vezérlést, mi következik azután, hol lép ki stb. Ez a szakasz tömören leírja a program vezérlésének globális lefolyását, majd megtárgyalja az alkalmazás inicializációs függvénye, az InitInstance által végrehajtott feladatokat. A következő lista néhány olyan jelentősebb eseményt tartalmaz, amelyek egy MFC program futtatása közben fordulnak elő. Azért ez az öt esemény került kiválasztásra, mert ezek segítenek nekünk legjobban megérteni azt, hogy miként is működik egy MFC program: 1. Meghívásra kerül a CWinApp osztály konstruktora 2. A program bemeneti függvénye, a WinMain, átveszi a vezérlést 3. A WinMain meghívja a program InitInstance függvényét 4. A WinMain belép egy, az üzenetek feldolgozására szolgáló ciklusba 5. A WinMain kilép és a program véget ér Részletesebben kifejtve: 1. Meghívásra kerül a CWinApp osztály konstruktora
Mint ahogy az korábban már megemlítettem, egy MFC alkalmazásnak pontosan egy példányt kell definiálnia az alkalmazásosztályából. A Probacpp fájl definiálja a Proba alkalmazás osztályának, a CProbaApp-nak egy példányát a következő globális definícióban: //////////////////////////////////////////////////////// // The one and only CWinGreetApp object CWinGreetApp theApp; 52 Mivel hogy a CProbaApp objektum globálisan definiált, így az osztály konstruktora azelőtt kerül meghívásra, mielőtt a program kezdeti függvénye, a WinMain átveszi a vezérlést. Az AppWizard által generált CProbaApp konstruktor általában nem csinál semmit: //////////////////////////////////////////////////////// // CWinGreetApp construction CWinGreetApp::CWinGreetApp() { // TODO: add construction code here, // Place all significant initialization in // InitInstance } Azonban egy ilyen „semmittevő” konstruktor azt okozza, hogy a fordító meghívja az ősosztály
(amely a CWinApp) alapértelmezett konstruktorát. A CWinApp konstruktor (amellyel az MFC szolgál) a következő két feladatot hajtja végre: - Megbizonyosodik arról, hogy a program csak egyetlen alkalmazás objektumot deklarál, azaz csak egy objektum tartozik a CWinApp-hoz vagy egy abból származó osztályhoz. - Elmenti a program CProbaApp objektumának a címét egy az MFC által deklarált mutatóba. Azért menti el ezt a címet, hogy az MFC kód később meghívhassa a ProbaApp tagfüggvényeket. Ezen tagfüggvények meghívása a 3 lépésben kerül megtárgyalásra. 2. A WinMain átveszi a vezérlést Az összes globális objektum létrehozása után a program kezdeti függvénye, a WinMain, átveszi a vezérlést. Ez a függvény az MFC kódon belül került definiálásra, a futtatható fájl felépítésekor szerkesztődik a Proba programhoz A WinMain függvény sok feladatot hajt végre. Az elkövetkező pontok írják le azokat a feladatokat, amelyek a legfontosabbak
ahhoz, hogy megérthessük a Proba program működését 3. A WinMain meghívja az InitInstance függvényt Röviddel az után, hogy átveszi a vezérlést, a WinMain meghívja a CProbaApp osztály InitInstance tagfüggvényét. E függvényt annak az objektum címnek a felhasználásával hívja meg, amelyet a CWinApp mentett el az 1 lépésben Az InitInstance az alkalmazás inicializálására szolgál. Az MFC a CProbaApp objektum címét egy olyan CWinApp mutatóba menti el, amelyet az InitInstance meghívására használ. Mivel az InitInstance egy virtuális függvény, így a CProba osztályon belül definiált InitInstance felüldefiniált változata veszi át a vezérlést. A CWinApp számos más olyan virtuális függvényt definiál, amelyeket később felüldefiniálhatunk. Például felüldefiniálhatjuk az ExitInstance függvényt, hogy az azonnal végső tisztogatást hajtson végre a program befejeződése előtt. 4. A WinMain üzeneteket dolgoz fel Miután befejezte az
inicializációs feladatait, a WinMain egy olyan ciklusba lép be, amely a Windows rendszert hívja ahhoz, hogy hozzájusson és elküldje az összes, a Proba programon belüli objektumoknak küldött üzenetet (ezt a ciklust ténylegesen egy Run elnevezésű CWinApp tagfüggvény tartalmazza, amely a WinMain-ból kerül meghívásra). A vezérlés ezen a cikluson belül marad az alkalmazás futásának 53 hátralevő részében. Windows 9x, valamint Windows NT alatt azonban az úgynevezett preemptív multitaszkolás lehetővé teszi más programok a jelenlegivel egyidejű futását. 5. A WinMain kilép és a program véget ér Amikor a Proba program felhasználója kiválasztja az Exit parancsot a File menüből vagy a Close parancsot a rendszermenüből vagy rákattint a Close gombra, az MFC kód bezárja a programablakot és meghívja a Win32 API függvényt, a ::PostQuitMessage-et, amely eredményeként az üzenetciklus véget ér. A WinMain függvény ezután visszatér s
eredményeként az alkalmazás lezáródik. Az InitInstance függvény Az InitInstance a CProbaApp alkalmazásosztály egy tagfüggvénye, definiálására a Proba.cpp forrásfájlban kerül sor Az MFC ezt a függvényt a WinMain-ból hívja, feladata pedig az alkalmazás inicializálása Az InitInstance meghívásának idején egy hagyományos Windows GUI alkalmazás egyszerűen létrehozna egy fő programablakot az MFC által használatos nézet-dokumentum programozási modell következtében. Azonban az AppWizard kód ennél egy picit összetettebben dolgozik Létrehoz egy dokumentum sablont, amely eltárolja a program dokumentum-, főablak- és nézetosztályáról szóló információkat A dokumentumsablon eltárolja egy dokumentum megjelenítésében és kezelésében használatos programerőforrások azonosítóját is (menü, ikon stb) Amikor a program először kezd el futni és létrehoz egy új dokumentumot, akkor a dokumentumsablont használja ahhoz, hogy létrehozza a
dokumentumosztály egy objektumát a dokumentum eltárolásához, a nézetosztály egy objektumát egy a dokumentum megjelenítéséhez használatos nézetablak létrehozásához és a főablak egy objektumát, hogy egy főprogram ablakkal szolgáljon a nézetablak bekeretezéséhez. Egy dokumentumsablon egy C++ objektum. Egy olyan SDI alkalmazás esetén, mint a Proba, a sablon a CSingleDocTemplate MFC osztály egy példánya. Az InitInstance-ban szereplő következő kód létrehozza a dokumentumsablont és elraktározza azt az alkalmazásobjektumon belül: // Register the applications document templates. // Document templates serve as the connection between // documents, frame windows, and views. CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR MAINFRAME, RUNTIME CLASS(CProbaDoc), RUNTIME CLASS(CMainFrame), // main SDI frame // window RUNTIME CLASS(CProbaView)) ; AddDocTemplate(pDocTemplate); Ez a kód a következőképpen működik: - Definiál egy
mutatót egy dokumentumsablon objektumhoz (ez a pDocTemplate). - A new operátor használatával dinamikusan létrehoz egy dokumentumsablonobjektumot (azaz a CSingleDocTemplate egy példányát), az objektum címét a pDocTemplate mutatóban tárolja. 54 - Átad négy paramétert a CSingleDocTemplate konstruktornak. Az első paraméter azon programerőforrások azonosítója, amelyek egy dokumentum megjelenítésében és kezelésében használatosak (nevezetesen a gyorsbillentyű-tábla, az ikon, a menü és egy leíró sztring). - A következő három paraméter szállítja a dokumentumosztályról, a főablakosztályról ás a nézetosztályról szóló információkat. Az egyes osztályokról szóló információkhoz a RUNTIME CLASS MFC makró meghívásával jut hozzá (amely makró egy CRuntimeClass objektumra mutató pointert ad vissza) Ezen információk biztosítanak lehetőséget arra, hogy a program dinamikusan létrehozhasson egy objektumot minden egyes
osztályból egy új dokumentum előszöri megalkotásakor - Az AddDocTemplate CWinApp tagfüggvénynek az a sablonobjektum-mutató kerül átadásra, amely a dokumentumsablont az alkalmazásobjektumon belül raktározza el úgy, hogy a sablon elérhető legyen egy dokumentum megnyitásakor. A dokumentumsablon létrehozása után az InitInstance a ParseCommandLine CWinApp tagfüggvény meghívásával kinyeri a program futtatásakor megadott parancssort, ha az létezik. // Parse command line for standard shell commands, DDE, // file open CCommandLinelnfo cmdlnfo; ParseCommandLine(cmdlnfo); Ezután meghívja a ProcessShellCommand CWinApp tagfüggvényt, amely feldolgozza a parancssort: // Dispatch commands specified on the command line if (! ProcessShellCommand(cmdlnfo) ) return FALSE; Ha a parancssor tartalmaz egy fájlnevet, akkor a ProcessShellCommand megkísérli megnyitni a fájlt. Normális körülmények között, ha futtatjuk a Proba programot (például a Developer Studio
révén), akkor a parancssor üres. Ebben az esetben a ProcessShellCommand meghívja az OnFileNew CWinApp tagfüggvényt egy új, üres dokumentum létrehozásához. Az OnFileNew meghívásakor a program a dokumentumsablont használja egy CProbaDoc objektum, egy CMainFrame objektum, egy CProbaView objektum és a kapcsolódó főablak valamint a nézetablak létrehozásához. A főablakhoz használatos erőforrások (menü, ikon stb.) azok, amelyek a dokumentumsablonban eltárolt erőforrásazonosító által azonosítottak Mivelhogy ezek az objektumok és ablakok belsőleg az OnFileNew által kerülnek létrehozásra, nem láthatjuk azokat a Proba kód explicit objektumdefinícióin belül s nem láthatunk ablakok létrehozására használatos függvényhívásokat sem. Valahányszor a felhasználó utólag kiválasztja a New parancsot a File menüben, az OnFileNew függvény kerül meghívásra. Egy SDI alkalmazásban azonban ezek az utólagos hívások nem hoznak létre új
objektumokat vagy ablakokat; ehelyett újra felhasználják azokat a már létező ablakokat és objektumokat, amelyek az OnFileNew első hívásánál kerültek létrehozásra Végezetül az InitInstance meghívja a főablak objektum ShowWindow és az UpdateWindow tagfüggvényeit, hogy a főablakot láthatóvá tegye a képernyőn, s hogy 55 ennek eredményeként az ablak tartalma megjelenjen. Ezeket a függvényeket a főablakobjektumra mutató pointer felhasználásával hívja Ez a mutató a CProbaApp objektum m pMainWnd adattagjában kerül eltárolásra (amelyet a CWinThread-ból örököl): // The one and only window has been initialized, so // show and update it. m pMainWnd->ShowWindow(SW SHOW); m pMainWnd->UpdateWindow(); Egyéb kódok az InitInstance-ban Az InitInstance meghívja a CWinApp::Enable3dControlsStatic függvényt (vagy az Enable3dControls függvényt, ha az osztott MFC DLL-t választjuk a korábban leírtak alapján), hogy a Windows megjelenítse a
háromdimenziós külsővel rendelkező kontrollokat (mint például a jelölőnégyzetek): // Standard initialization // If you are not using these features and wish to // reduce the size of your final executable, you // should remove from the following the specific // initialization routines you do not need. #ifdef AFXDLL Enable3dControls(); // Call this when using MFC // in a shared DLL #else Enable3dControlsStatic(); // Call this when linking // to MFC statically #endif Az InitInstance meghívja a SetRegistryKey CWinApp tagfüggvényt is, amely eredményeként a programbeállítások a Windows Registry-ben kerülnek eltárolásra (egy .ini fájl helyett) és meghatározza azt a kulcsnevet is, amely alatt ezek a beállítások eltárolásra kerülnek: // Change the Registry key under which our settings are // stored. You should modify this string to be // something appropriate such as the name of your // company or organization. SetRegistryKey( T( "Local AppWizard-Generated
Applications")); Ahhoz, hogy megváltoztassuk azt a kulcsnevet, amely alatt a programbeállítások eltárolásra kerülnek (például saját magunk nevére), egyszerűen csak helyettesítsük a SetRegistryKey-t követő sztringet egy másikkal. (A T makró konvertálja a sztringet arra az Unicode formátumra, amelyet a SetRegistryKey megkövetel. Ez a formátum az egyes karaktereket 16 bites értékként tárolja és felhasználható karakterek bármilyen nyelven történő kódolására.) A Registry-ben eltárolt elsődleges beállítás a legújabban megnyitott dokumentumok listája, amelyet a program File menüje is megjelenít (s amely MRU vagy Most Recently Used listaként is ismeretes). Az InitInstance ezt a dokumentumlistát és bármilyen más a Registry-ben tárolt program beállítást is a CWinApp::LoadStdProfileSettings függvény meghívásával tölti be: LoadStdProfileSettinqs(); // Load standard INI file 56 Ha szükségünk van bármilyen más
alkalmazás-inicializációs feladat végrehajtására, akkor az InitInstance függvény a megfelelő hely, ahová a szükséges kódot beilleszthetjük. Üzenetkezelő függvények készítése Ha lehetővé akarjuk tenni a felhasználó számára, hogy az egérrel bármit kijelöljön a nézetablakban, vagy bármelyik nem előredefiniált menüpontot használhassa, a programnak le kell kezelnie az ebben az ablakban bekövetkező egér és egyéb eseményeket. Az egérműveletek feldolgozásához egy új tagfüggvényt kell beillesztenünk a nézetosztályba, amely a nézetablakba érkező egérüzeneteket kezeli. A Windows GUI programokban minden ablakhoz kapcsolódik egy függvény, melyet ablakkezelő eljárásnak (window procedure) nevezünk. Amikor valamilyen fontos esemény következik be, amely kihat az ablakra, akkor az operációs rendszer meghívja ezt a függvényt és átad neki egy azonosítót, amely meghatározza az eseményt, valamint minden olyan további kapcsolódó
adatot, amelyek az esemény kezeléséhez nélkülözhetetlen. Ezt a folyamatot nevezzük a Windowsban az üzenetküldésnek Amikor egy ablakot az MFC osztályok segítségével hozunk létre, és ezekkel kezeljük a továbbiakban is, akkor az MFC elkészíti számunkra az ablakkezelő eljárást. Az MFC által adott ablakkezelő eljárás minden olyan üzenettípushoz, amit az ablak megkaphat, egy minimális, alapértelmezett kezelőt biztosít. Ezért ha saját üzenetkezelést akarunk megvalósítani egy bizonyos típusú üzenethez, akkor készíthetünk egy üzenetkezelő függvényt, amelyet az ablakkezelő osztály tagfüggvényeként kell létrehoznunk. Használhatjuk a ClassWizard-ot az üzenetkezelő függvények létrehozására egy adott osztály esetén. Például, ha a felhasználó lenyomja a bal egérgombot miközben az egérkurzor a nézetablakon belül helyezkedik el, akkor a nézetablak egy üzenetet kap, amelynek azonosítója WM LBUTTONDOWN. Ha ezt az üzenetet
saját magunk szeretnénk feldolgozni, akkor a ClassWizard segítségével készíthetünk egy tagfüggvényt a program nézetosztályában, amely ezt az üzenetet kezeli Az MFC speciális kezelőeljárást valósít meg azon üzenetek esetében, amelyeket a felhasználói felület objektumai hoznak létre. A felhasználói felület objektumai olyan szokásos interfész elemek, amelyeket az MFC támogat Ide tartoznak a menüpontok, a gyorsbillentyűk, az eszköztárak nyomógombjai, az állapotsor jelzői és a párbeszédablakok vezérlői is. A felhasználói felület objektumai által létrehozott üzeneteket nevezzük parancs-üzeneteknek. Amikor a felhasználó kiválaszt egyet a felhasználói felület objektumai közül, vagy valamilyen más okból szükséges ezen objektumok frissítése, az objektum egy parancsüzenetet küld az elsődleges (vagy frame = keret) ablaknak Az MFC azonban azonnal átirányítja az üzenetet a nézetobjektumnak. Ha a nézetobjektum nem kezeli le az
adott üzenetet, akkor az MFC a dokumentum objektumhoz irányítja azt. Ha a dokumentum objektumban sem szerepel megfelelő kezelőfüggvény, akkor kerül az üzenet az elsődleges ablakhoz. Az átirányítások még mindig nem feltétlenül érnek véget, mert ha az elsődleges ablak nem ad kezelőt, akkor az üzenet az alkalmazás objektumhoz kerül, és csak akkor fut le a minimális, alapértelmezett feldolgozás, ha az alkalmazás objektumban sem dolgozzuk fel az üzenetet Tehát az MFC kibővíti a Windows üzenetek alapszolgáltatását, hiszen az üzeneteket nem csak az ablakot kezelő objektumok dolgozhatják fel, hanem a program bármely más fő objektuma is. (Ezek az objektumok mindannyian olyan osztályhoz tartoznak, amely - közvetlenül vagy közvetve - az MFC CCmdTarget osztályából származik. Ez az osztály nyújt támogatást az üzenetek kezeléséhez.) 57 Egy fontos következménye az MFC parancsüzenet feldolgozó módszerének, hogy a program minden egyes
parancsüzenetet a legmegfelelőbb osztályban dolgozhat fel. Például az AppWizard segítségével készült programok esetén az File menü Exit parancsát az alkalmazás objektum dolgozza fel, mert ez a parancs az alkalmazás egészét érinti. Ugyanakkor a File menü Save parancsát a dokumentum osztály kezeli le, hiszen ennek az osztálynak feladata a dokumentum adatainak tárolása és mentése. 58 5.2 Scard (bővebben: a Towitoko AG honlapján a http://www.towitokode címen) A szakdolgozat elkészítéséhez nélkülözhetetlen irodalom volt az ScardServer V2.14 Technical Documentation, amelynek legújabb verziója az említett honlapon elérhető. A Towitoko AG nemcsak szinte a legolcsóbb kártyaolvasókat nyújtja, hanem komoly háttérbázist tart fenn a termékeit felhasználó programozók és egyszerű felhasználók igényeinek kielégítésére. 5.21 Áttekintés Az ScardServer önállóan végzi el a csatlakoztatott kártyaolvasó terminálok menedzselését:
- Plug&Play támogatás - Az olvasó terminálok listájából a névre kattintva egyszerűen kiválaszthatjuk mely olvasót kívánjuk használni, hasonlóan ahhoz, mint a nyomtató kiválasztásánál. pl.: „CHIPDRIVE extern at COM1” - Minden terminál státuszát tárolja, s ezáltal könnyen ellenőrizhető, pl.: kártyastátusz, sorozatszám vagy egyéb terminál információk. - A legutóbbi konfigurációs állományok eltárolása INI-fájlban Az ScardServer a kiszolgált alkalmazások menedzselését is végzi: - A jelenleg a szerverhez csatlakozó alkalmazások figyelése - Az ScardServer megoldja a lockolást, egyidejűleg két alkalmazás nem érheti el az olvasót. Amikor az alkalmazás befejezte a kártyán végzett műveleteket, akkor a szerver átadja a kártyával kapcsolatos jogokat a következő alkalmazásnak. - A kívánt alkalmazást egy adott típusú kártyával regisztrálva elérhető, hogy e típusú kártyák behelyezése esetén
automatikusan elinduljon a kívánt alkalmazás. Memóriakártyák kezelésére is alkalmas: - A chip típus és különböző paraméterek automatikus felismerése, úgymint PIN kód megadásának lehetősége, írásvédelem, sőt I²C kártyák támogatása is. - Adott alkalmazás adatainak automatikus felismerése - Egységes parancskészlettel érhetők el az adatok, függetlenül a kártya típusától. Pl: Card,MemWrite vagy Card,ISOAPDU - TLV adatok (Tag Length Value kódolás) azonnali elérése - Olvasási és írási cache-elés a maximális teljesítmény érdekében - PIN kód kezelése - Jelenleg több mint 50 különböző chipkészletet támogat, a legfrissebb lista letölthető a http://www.towitokode/ címen Processzorkártyák sokrétű kezelése: - A kártyatípus automatikus felismerése az ATR (Answer to Reset) kiértékelése - Támogatja a közvetlen parancsküldést a kártyának, melyet a kártya egy az egyben megkap, mindennemű
protokollfejléc nélkül. 59 - T0 és T1 protokollok teljes mértékben használhatók az ISO7816-3 szerint, beleértve a hibakezelést és egyéb lehetőségeket. - A T0 és T1 protokoll paraméterei automatikusan beállítódnak az ATR-nek megfelelően, mellyel sok felesleges rutinmunkától mentesülünk. - APDU támogatás a kívánalmaknak megfelelően (ISO7816-4, GSM11.11 vagy CTAPI szerint) Szabványos kártyaformátumok támogatása: - Német betegbiztosítási kártya (“Krankenversichertenkarte“ - Apps,KVK) - Német telefonkártya (“Telefonwertkarte“ - Apps,TWK) 5.22 Az Scard interfész Az Scard a legkényelmesebben használható, legegyszerűbben megtanulható interfész, mely manapság elérhető. Az interfész eleve azért lett kifejlesztve, hogy az ScardServer mindennemű lehetőségeit ki lehessen aknázni. Az ScardServer a PC/SC parancsok teljes támogatást nyújtja amellett, hogy megkönnyíti az intelligens kártyák programozásában kevésbé
tapasztalt programozók dolgát. Azért, hogy az intelligens kártyák különböző programokból való elérése a lehető legegyszerűbb lehessen, az ScardServer minden egyes utasításának szintaxisa megegyezik. A kiadható függvényhívások és a paraméterek átadása úgy történik, hogy egy utasítássztringet kell megadnunk. A bemenő és/vagy kimenő adatok opcionálisak Az utasítássztring mindig kulcsszavakat, valamint vesszővel elválasztott paramétereket tartalmaz. Az utasításokat a következő hármassal adhatjuk meg: Command, DataIn, DataOut, ahol a Command az utasítás, a DataIn az utasításhoz szükséges bemenő adat, míg a DataOut a visszakapott kimenő adat. 1. példa: A jelenlegi terminál típusának lekérdezése A várható hibakódok: 0 = „OK” Command: Str( „Device,Info,Type” ) DataIn: nil DataOut: Str( „CHIPDRIVE extern” ) 2. példa: 21 bájt kiírása egy memóriakártyára a 16-os memóriacímétől kezdve A várható hibakódok: 0 =
„OK”, 0x4000=„No card present in terminal”, 0x1009=„Terminal is locked” Command: Str( „Card,MemWrite,16,21” ) DataIn: Str( „Hello SmartCard World” ) DataOut: nil Az iménti példák kipróbálásához nem szükséges bárminemű inicializáció vagy egyéb adminisztratív utasítások végrehajtása, egyből nekifoghatunk a kártyaműveleteknek. Ráadásul nagyszámú hasznos lehetőséget tartogat az interfész még a tapasztalt kártyaprogramozók számára is. 5.23 DLL függvények Az interfész minden függvényhívása közvetlenül egy DLL függvényhívásnak felel meg. Az Scard függvényhívások csak akkor térnek vissza, miután a szerver feldolgozta az 60 adott utasítást, habár a Windows üzenetek feldolgozása a szokásos módon történik az utasítás végrehajtása alatt is. Az Scard interfész utasításai rekurzív függvényhívás esetén négyszintű rekurziót támogatnak Felhasználói programból történő híváshoz az alábbi DLL-ek
valamelyikét kell használnunk: 16 bit: SCARD.DLL, 32 bit: SCARD32DLL Mindkettő hívási formátuma a következő: Response = SCardComand (Handle, Cmd, CmdLen, DataIn, DataInLen, DataOut, DataOutLen); LPINT Handle /* pointer egy 32 bites előjeles integerre / LPSTR Cmd /* pointer egy karaktersztringre / LPINT CmdLen /* pointer egy 32 bites előjeles integerre / LPSTR DataIn /* pointer egy bájtokból álló tömbre, vagy karaktersztringre / LPINT DataInLen /* pointer egy 32 bites előjeles integerre / LPSTR DataOut /* pointer egy bájtokból álló tömbre, vagy karaktersztringre / LPINT DataOutLen /* pointer egy 32 bites előjeles integerre / INT Response /* 32 bites előjeles integer / Részletesen: Handle: Több DLL használata esetén ez alapján válik megkülönböztethetővé melyik funkcióit akarjuk használni. Egy DLL használata esetén az értéke akár nulla is lehet Ebben az esetben az ScardServer az alkalmazás szál- és taszkkezelését felhasználva tudja elvégezni
a kívánt funkciókat. Cmd: Az ScardServer utasítás (nullára végződik - zero terminated). CmdLen: Az ScardServer utasítás hossza, ha az adatfolyam titkosítva van a szerver felé, egyébként nulla. DataIn: A bemeneti adatokra mutató pointer. DataInLen: A bementi adatok hossza. DataOut: A kimeneti adatokra mutató pointer. DataOutLen: A kimeneti adatok maximális hossza. Visszatérés után a kimeneti adatok pontos hosszát tartalmazza. Response: Általános visszatérési érték. Visszatérés után az értéke nulla, ha az utasítás végrehajtása sikeres volt. Dinamikus implementáció: typedef DWORD ( stdcall *SCardCmd)(LPDWORD Handle, LPCSTR Cmd, LPINT CmdLen, LPCSTR DataIn, LPINT DataInLen, LPCSTR DataOut, LPINT DataOutLen); (.) SCardCmd pSCardCommand = NULL; HANDLE hScardDLL = LoadLibrary("SCARD32.DLL"); if (hSCardDLL) pSCardCommand = (SCardCmd)GetProcAddress(hScardDLL, "SCardComand"); Ha a 16 bites változatot szeretnénk használni, akkor az
SCARD.DLL-t kell betölteni: . = LoadLibrary("SCARDDLL"); 61 Ennyi teendőnk van, mielőtt bármilyen kártyaműveletet is végeznénk, ezután következhet a parancsvégrehajtás. Nincsenek LIB fájlok, miáltal statikus importot alkalmazhatnánk, kizárólag dinamikus importot használhatunk Jó tanács, hogy a sztringváltozókat mindig ellenőrizzük a végrehajtás előtt! 5.24 Kártyastátusz Az ScardServer végzi a kártya kezelését, miáltal minden alkalmazás a következő információkat érheti el a kártya és az olvasó állapotára vonatkozóan: (Az egyes státuszértékekhez tartozó hibaüzenetek szövegét az scard.err fájl tartalmazza, mely a c:Windows alkönyvtárban található a számítógépen.) - Az olvasó állapota lekérhető, hogy csatlakoztatva van-e és válaszol-e normálisan. Hiba esetén a státusz: ERROR. - Ha nem áll rendelkezésre kártya az olvasóban, a státusz: WAIT. - Ha behelyezünk egy kártyát, elindul az automatikus
felismerési folyamat és meghatározza a chip pontos típusát, és ezután megpróbálja felismerni, hogy ismert kártyatípusról van-e szó. Amíg fut az automatikus felismerés, addig a státusz: DETECT A kártya nem érhető el ebben az állapotban. (hibakód: 0x4000=„No card present in terminal”) - Ha a kártya nem olvasható, vagy valamilyen hiba lép fel a felismerési folyamat során, akkor a státusz: INVALID. - Ezután a kártya lefoglalódik pontosan egy alkalmazás számára. Ez az alkalmazás az ACTIVE státuszt kapja, míg minden más alkalmazás LOCKED státuszt. - Ez mindaddig fennmarad, amíg: a) A kártyát ki nem veszik, a státusz újra: WAIT. b) A Card,Unlock utasítás kiadásra nem kerül az aktív alkalmazás részéről. - A b) feltétel esetén az ScardServer lefoglalja a kártyát a következő alkalmazás számára, ami újra továbbadhatja azt a rákövetkezőnek. - Ha minden alkalmazás „elengedte” a kártyát a Card,Unlock utasítás
használatával, akkor a státusz VALID lesz. - Ha egy alkalmazásnak újra szüksége van a kártyára, akkor ki kell adnia a Card,Lock utasítást. Az alkalmazás számára a kártya ACTIVE státuszú lesz, míg minden más alkalmazás számára LOCKED. - Az aktív alkalmazás újra „elengedheti” a kártyát, és annak státusza ekkor újra VALID lesz. Az aktuális kártyastátusz a Card,Info,Status utasítással kérdezhető le. Windows üzenetkezelés: Windows rendszer alatt sokkal hatékonyabb a kártyastátusz változásának figyelése a Windows üzeneteinek segítségével. Ugyanis lecsökken a rendszerterhelése, mivel nem szükséges ciklikusan ismételgetni a kártyastátusz lekérdezését. Ez ugyanis egy olyan ciklusmagot tartalmazna, melyben az alkalmazói program a processzor és a memória elérésével meghív egy másik alkalmazást, az ScardServert, amely szintén processzoridőt 62 és memóriát fogyaszt, azután ez meghívja a Windows operációs
rendszert, az az alrendszereit és így tovább egészen addig, amíg ki nem derül a kártya státusza. Lehetséges ugyanis regisztrálni (és deregisztrálni) bármely alkalmazás számára az ScardServer üzeneteit a System,AddHWndMsg és System,DelHWnd utasítások használatával. Ebben az esetben az iménti ciklus csak magában a hardverben következik be, amely nem lassítja a rendszer működését. Egy üzenet érkezik az alkalmazásunk számára az alábbi esetekben: - A státusz megváltozott: WAIT DETECT - Az aktív alkalmazás továbbadta a kártyát a sorban következőnek, habár a státusz még mindig LOCKED. Nem érkezik üzenet viszont akkor, ha az alkalmazásunk jelezte igényét a kártyára a Card,Lock utasítással és mi kapjuk meg a kártyát: VALID ACTIVE Minden más alkalmazás üzenetet kap a VALID LOCKED státuszváltozásról. A kivétel oka az, hogy az ACTIVE üzenetet csak közvetlenül a kártya behelyezése utáni első alkalmazás kapja. Az
üzenetet a megadott window handle-nek a PostMessage API funkció segítségével küldi. Az üzenet regisztrálása a System,AddHWndMsg utasítással történik Az üzenet W-paramétere adja meg a státusz értékét: - MsgError = decimális 100, ERROR esetén - MsgWait = decimális 110, WAIT esetén - MsgDetect = decimális 120, DETECT esetén - MsgInvalid = decimális 130, INVALID esetén - MsgValid = decimális 140, VALID esetén - MsgActive = decimális 150, ACTIVE esetén - MsgLocked = decimális 160, LOCKED esetén - MsgProgress = decimális 200, százalékértékek kijelzésére memóriakártya elérése közben - MsgDeviceList = decimális 300, az olvasóeszközök listájának megváltozása esetén - MsgDeviceSearch = decimális 301, százalékértékek kijelzésére olvasóeszköz keresése közben - MsgTaskList = decimális 310, a taszklista megváltozása esetén - MsgCardInfo = decimális 320, a CardInfo lista megváltozása esetén Az
L-paraméter alacsony része (word) jelzi az aktív kártyaolvasó indexét kártyaolvasók listájában (nullától kezdve). Kivétel a MsgDeviceSearch: itt a COM-Port, amelyet ellenőrzünk. Az L-paraméter magas része (word) az üzenettől függ: - MsgLocked: az aktív alkalmazás indexe a taszklistában (nullától kezdve) - MsgProgress: elkészültség foka 0-tól 100 %-ig 63 - MsgDeviceSearch: elkészültség foka 0-tól 100 %-ig, speciális értékek a 254: olvasó OK; 255: Nincs olvasó. Az üzenetek deregisztrálása az SCardComand következő felparaméterezésével lehet: Cmd = nil, CmdLen = 0, DataIn = nil, DataInLen = 0, DataOut = nil és DataOutlen = -1. Ha a DataOutlen = -2, akkor ez újraaktiválja a folyamatot. 5.25 Több alkalmazás esete Minden alkalommal, amikor egy alkalmazás továbbadja a várakozási lista következő elemének a kártyát, a kártyán a Card,Reset utasítás kerül végrehajtásra. Az aktív alkalmazás kiválasztásának feladata az
ScardServer-re hárul. A prioritás meghatározása az alábbiak szerint történik, ebben a sorrendben: - egy alkalmazás egy speciális kártyatípust regisztrált, pl.: a SIM-Surf, ami GSM kártyákat - a bennlévő processzorkártya nevét (ISO7816-4) regisztrálta az alkalmazás - a bennlévő memóriakártyára illeszkedik a regisztrációs maszk (adott memóriahely összehasonlítása) - az ATR-ben specifikáltaknak megfelelően lett regisztrálva Ha több alkalmazás is egyaránt alkalmas, vagy egyaránt nem igaz egyik kikötés sem, akkor a Windows desktop tab sorrendje alapján történik választás. Elősegítendő a többalkalmazásos környezetet, mindig csak annyi időre blokkoljuk a kártyát, ameddig tényleg szükség van rá! 5.26 Hibakódok Az SCARD.ERR fájl tartalmazza a hibaüzeneteket Ez installálás után általában a c:Windows alkönyvtárban található, és még nem tartalmazza a magyar verziót. Ezért érdemes lecserélni a CD-mellékleten
található verzióra. Más nyelvre történő fordítás esetén csak adjunk hozzá a fájlhoz egy, a meglévőkhöz hasonló szakaszt! Következzenek a hibakódok (hexadecimálisan), hibaüzenetek (magyar és angol nyelven) és magyarázataik: 0x0000 „OK” 0x0000 „OK” (A parancsot sikerült végrehajtani.) 0x1001 „Serial port not available” 0x1001 „A soros port nem elérhető” (A keresés a megadott COM porton nem lehetséges, mivel a port nem elérhető. A portot konfiguráljuk úgy, hogy felismerje a rendszer!) 0x1002 „Serial port is used by another application” 0x1002 „A soros portot egy másik alkalmazás használja” (A COM-portot egy másik eszköz vagy alkalmazás használja, például: mouse vagy modem.) 0x1008 „No terminal detected on selected port” 0x1008 „A kártyaolvasó nem elérhető” 64 (A COM-port elérhető, azonban nem észlelhető rajta kártyaolvasó, ellenőrizze a csatlakozásokat és kábeleket!) 0x1009 „Terminal is locked by
X” 0x1009 „X használja a kártyaolvasót” (Pillanatnyilag nem lehetséges elérni a kártyaolvasót, mivel egy másik alkalmazás éppen használja a kártyát, vagy csak nem szabadította még fel a lefoglalást. Az “X“ a megfelelő alkalmazás neve.) 0x4000 „No card present in terminal” 0x4000 „Nincs kártya a kártyaolvasóban” 0x4001 „Card was removed during access” 0x4001 „Hozzáférés közben a kártyát eltávolították” 0x4002 „Invalid card present in terminal” 0x4002 „Érvénytelen kártya” 0x4004 „Card ejection failed” 0x4004 „A kártya kiadása nem lehetséges” (Ezek a hibaüzenetek olyan későbbi fejlesztésekre vannak fenntartva, amikor a kártyát már nem kézzel kell behelyezni, hanem automatika vezérli azt.) 0x1200 „Unknown command” 0x1200 „Érvénytelen utasítás” (Az utasítássztring értelmetlen, vagy nem támogatott utasítást tartalmaz.) 0x1201 „Command execution not possible with current card” 0x1201
„A kártyán az adott utasítás nem használható” (Nem minden utasítás használható minden kártyán, különösen, hogy bizonyos utasítások csak memóriakártyán, bizonyosak csak processzorkártyán használhatók.) 0x1202 „Command execution not possible with this terminal” 0x1202 „A kártyaolvasón az adott utasítás nem használható” (A terminál nem minden típusú kártyát támogat, például bizonyos olvasók nem ismerik fel a processzorkártyákat, ekkor egy T0 utasítás a fenti hibát okozza.) 0x1203 „Invalid command parameter” 0x1203 „Az utasítás paramétere hibás” (Érvénytelen címzés, vagy a memóriaterületen kívüli részre történő hivatkozás a Card,MemRead utasítás esetén.) 0x1310 „Smartcard access failed” 0x1310 „Hozzáférés megszakadt” (Nem visszaállítható hiba lépett fel a kártyaműveletek végrehajtása közben.) 0x1311 „PIN error! X trial(s) left” 0x1311 „Hibás PIN kód! Még X próbálkozás
maradt” (A memóriakártya PIN kóddal védett, és a megadott PIN kód nem megfelelő. Még “X“ próbálkozás maradt.) 0x2000 „Server not available” 0x2000 „A kiszolgáló-alkalmazás nem elérhető” (Az ScardServer nem indult el, vagy időközben leállt.) 5.27 Utasításkészlet Az utasításkészlet fa-szerkezetben ábrázolható, mivel témakörökre osztható, azok újabb témakörökre stb. A kiadott utasítások formátuma is ezt mutatja, például a 65 System,Info,ErrCode a Rendszer (system) témakörön belül az Információk (Info) témakör egyik elemét, az utolsó hiba kódját (ErrCode) kérdezi le. Ha az általunk megadott utasítássztring nem egy utasítás, hanem egy több utasítást tartalmazó témakör, ez esetben, ha a témakör tartalmaz lekérdezéseket, akkor általában az összes lekérdezés eredményének konkatenációját kapjuk. Például az előbbi utasítás a „ErrCode=4002” sztringet eredményezheti, míg a teljes témakör
lekérdezése esetén (System,Info) érkező válasz például: „Handle=3 Lng=ENGLISH VersionCode=0214 VersionText=CardServer V2.1415 ErrCode=4002 ErrText=Invalid Card present in terminal UsedMemHeap=312092 UsedMemTotal=1048576” A kiadható utasítások száma folyamatosan növekszik, köszönhetően a folyamatos újításoknak. Hogy mégis megtudhassuk melyek a kiadható új utasítások, témakörök (melyek akár még a legújabb dokumentációban sem szerepelnek) erre a célra szolgál a System,Comands utasítás. Utána vesszővel elválasztva kell megadni a témakört, amelynek a kiadható utasításaira, témaköreire kíváncsiak vagyunk. A jelenlegi teljes utasításkészlet a következő: System Info ErrCode ErrText Handle Lng UsedMemHeap UsedMemTotal VersionCode VersionText TaskList Create Destroy TaskTitele TaskPath AddHWndMsg DelHWnd SetMainHWnd SetLng ConvertErrCode Comands CryptKey DES GenCryptKey DES Device Info Status Port Type ShortName Index 66 Version
Serial LotNr Baudrate MaxBaudrate Led Caps Mode MouseDetect PowerFail CheckPowerFail List Refresh Select SearchComPort Remove InfoDeviceID InfoDeviceIDCard SetLed SetMode Card Info Status LockedBy LinkerApps LinkerCards PtsAuto PtsBinary PtsBinaryLen Baudrate CardCount CardPower Type Protocol ATR Apps MemSize PinSize PinCnt PageSize ErrMem ErrMemPB AtrBinary AtrBinarySize AtrHistory AtrHistorySize TS, T0, TA1.TD8 SAD DAD IFSC IFSD CWT BWT Lock Unlock 67 APDU ISOAPDU Reset T0TX T0RX T1 PTS TspTxRxLen InitBwtCwt InitSadDad InitIfsdIfsc MemDisableCache MemEnableCache MemRead MemWrite MemVerify MemReadPB MemWritePB MemVerifyPB MemSetPB MemReadStatus MemVerifyPin MemChangePin MemSpecial Deduct ProgUser ProgAuxData Apps TLV List ReadTag WriteTag TWK Seriennummer Hersteller Datum Orginalwert Restwert Chipcode ChipHersteller Betreiber KVK Krankenkasse KNummer VkNr VNummer Status StatusExt Titel Vorname Zusatz Name GebDatum Strasse Land 68 PLZ Ort Gultigkeit Az egyes utasítások
bemutatására terjedelmi okokból nem vállalkozom, csupán az általam is használtakat ismertetem. Mindemellett a ScardServer technikai dokumentációja minden, az intelligens kártyákat Scard interfész alatt programozni kívánó olvasó számára kiemelten fontos. Ezért az eredeti, angol nyelvű dokumentáció megtalálható a CDmellékleten, vagy bárki letöltheti a Towitoko AG honlapjáról a http://wwwtoitokode internetcímen. 5.271 System,Info Az ScardServer és a kiadott utasítások végrehajtásáról szóló információk lekérdezésére használatos. Command: Str( „System,Info[,<Field>]” ) DataIn: nil DataOut: Str( „<Data1>#13#10 [<Data2>#13#10[.]]” ) <Field>: Opcionális, az alábbiak egyike lehet: „ErrCode” - Az utolsó utasítás hibakódja. „ErrText” - Az utolsó utasítás során felmerült hibaüzenet. „Handle” - Handle, a DLL meghívásához használjuk. „Lng” - Az aktuális nyelvi beállítás (a
hibaüzenetekhez). „UsedMemHeap” - Az ScardServer által használt Heap mérete (bájtokban). „UsedMemTotal” - Az ScardServer által használt memória mérete (bájtokban). „VersionCode” - Az ScardServer verziószáma (4 jegyű BCD-kódolt). „VersionText” - Verziószám sztringként. <DataX>: A visszatért adatok. 1. Példa: System,Info minden mező értékével visszatér, ezeket CR+LF (#13#10) választja el Command: Str( „ System,Info” ) DataIn: nil DataOut: Str( „ Handle=3 Lng=ENGLISH VersionCode=0214 VersionText=CardServer V2.1415 ErrCode=4002 ErrText=Invalid Card present in terminal UsedMemHeap=312092 UsedMemTotal=1048576” ) 2. Példa: Csak egy adott mező értékére vagyunk kíváncsiak: Command: Str( „System,Info,Lng” ) DataIn: nil DataOut: Str( „ENGLISH” ) 5.272 System,SetLng Beállítja a hibaüzenetek nyelvét. Az SCARDERR aktuális szakaszának címkéjét használva a hibaüzenetek szövege az ott megadott lesz 69 Command: Str(
„System,SetLng,<LngStr>„ ) DataIn: nil DataOut: nil <LngStr>: Nyelv azonosítója az SCARD.ERR fájlban Példa: A magyar nyelv beállítása (csak az általam készített fájl tartalmazza!). Command: Str( „System,SetLng,MAGYAR” ) DataIn: nil DataOut: nil 5.273 Card,APDU Ez az utasítás egy APDU-t küld az intelligens kártyának, majd visszatér a kártya válaszával. A támogatott APDU típusok (ISO7816-4 szerint): - ‘Case 1’ vagyis P3=0, azaz se DataIn, se DataOut - ‘Case 2 short’ vagyis P3 maximum 254, és nincs DataIn, csak DataOut - ‘Case 3 short’ vagyis P3 maximum 254, és csak DataIn van, nincs DataOut - ‘Case 4 short’ vagyis P3 maximum 254, és van DataIn és DataOut A GSM speciális státuszértékei (9Fxx, 61xx és 6Cxx) nincsenek automatikusan értelmezve. Command: Str( „Card,APDU” ) DataIn: <CLA><INS><P1><P2>[<LC><DataIn>][<LE>] DataOut: <SW1><SW2>[<DataOut>]
<CLA><INS>: Utasításosztály és utasításkód, egy-egy bájt. <P1><P2>: Paraméter 1 és 2, egy-egy bájt. <LC><DataIn>: Opcionális, <LC> (egy bájt) megadja, hogy hány bájtot küldünk a kártyának, a <DataIn> tartalmazza a küldött adatokat. <LE>: Opcionális, egy bájt, hány bájtot várunk a kártyáról a <DataOut>-ban. <SW1><SW2>: Státusz Word, első és második bájt. <DataOut>: Opcionális, ha a <LE> megadja a beolvasni kívánt hosszt. A következő típusok vannak támogatva: (Maximális adatblokk méret: 254 bájt.) - ISO CASE 1: Nincsenek adatok. DataIn: <CLA><INS><P1><P2> DataOut: <SW1><SW2> Példa: DataIn: 0x00 0x42 0x05 0x01 DataOut: 0x90 0x00 - ISO CASE 2 short: A kártyáról adatok érkeznek (<Le>: 0x00 - 0xFF). DataIn: <CLA><INS><P1><P2><LE> DataOut: <SW1><SW2><DataOut> Példa:
DataIn: 0x00 0x42 0x05 0x02 0x03 DataOut: 0x90 0x00 0x54 0x57 0x4B - ISO CASE 3 short: A kártyára adatok továbbítódnak (<Lc>: 0x01 - 0xFF). DataIn: <CLA><INS><P1><P2><LC><DataIn> 70 DataOut: <SW1><SW2> Példa: DataIn: 0x00 0x42 0x05 0x03 0x03 0x54 0x57 0x4B DataOut: 0x90 0x00 - ISO CASE 4 short: Adatok küldése a kártyára és fogadása onnan (<Lc>: 0x01 0xFF, <Le>: 0x01 - 0xFF). DataIn: <CLA><INS><P1><P2><LC><DataIn><LE> DataOut: <SW1><SW2><DataOut> Példa: DataIn: 0x00 0x42 0x05 0x04 0x03 0x54 0x57 0x4B 00x4 DataOut: 0x90 0x00 0x4A 0x55 0x50 0x21 71 5.3 ETSI szabványok (bővebben: a http://www.etsiorg internetcímen) Számos ETSI szabvány közül négy bír kiemelkedő jelentőséggel a szakdolgozat elkészülte szempontjából. A GSM 1111 a SIM kártya funkcióit definiálja, a GSM 411 többek között az SMS szolgáltatás
protokolljának felépítését tartalmazza, a GSM 340 az SMS tartalmának pontos leírását adja meg, míg a GSM 3.38 meghatározza a használt karakterkészlet kódtábláját. Ilyen sorrendben kívánok foglalkozni a témákkal 5.31 GSM 1111 A GSM 11.11 a „Digital cellular telecommunications system (Phase 2+); Specification of the Subscriber Identity Module - Mobile Equipment (SIM - ME) interface” címet viseli, amely magyarul kb. annyit jelent, hogy a digitális celluláris telekommonikációs rendszerek SIM (felhasználói azonosító modul) - ME (mobiltelefon-készülék) közötti felület definíciója. A szabvány számos részletkérdést szabályoz, hiszen több, mint száz oldalas. Bizonyos témakörökre csak nagy vonalakban térek ki, hiszen egyrészt az apró betűs szabvány lefordítása rengeteg időt venne igénybe, másrészt a terjedelmi korlátok miatt inkább a CD-mellékleten található meg. Véleményem szerint, aki valamennyire is foglalkozik a
számítógépek programozásával, az legalább olvas angolul olyan szinten, hogy a szabvány szövegét egy szótárt kézbe véve akadály nélkül megértse. 5.311 Általános információk A SIM kártyának működni kell -25°C és +70°C hőmérséklet között, beleértve néhány alkalmat, amikor a hőmérséklet +85°C-ig is emelkedhet. A „néhány” azt jelenti, hogy 4 óránál rövidebb ideig tart ez az állapot, és a SIM kártya életében maximum 100 ilyen alkalom fordulhat elő. A kártya C4 és C8 kivezetései (lásd korábbi ábrát az ISO7816 szabványnál) nem bírnak funkcióval, ha a kártya csupán GSM kártya. Ha a kártya a GSM szolgáltatások mellett más szolgáltatásokat is nyújt, akkor ezeknek a kivezetéseknek is lehet funkciója. A SIM kártya működési árama: Symbol Minimum Maximum Unit Vcc 4,5 5,5 V 10 mA Icc Semmilyen frekvencia esetén nem haladhatja meg a megadott áramerősséget a fogyasztás. Ha a SIM várakozó állapotban
van, akkor a SIM fogyasztása nem haladhatja meg a 200 µA-t 1 MHz-en 25°C-on. A megadott erősségű elektromos szükségletet a telefonkészüléknek kell biztosítani. A SIM kártyának működni kell 1-től 5 MHz-ig terjedő frekvenciájú órajellel. Az órajelet a telefonkészülék biztosítja Nem használható belső órajelű SIM kártya (internal clock SIM). Ha a 13/4 MHz-es frekvencia használata szükséges, azt a SIM kártyának jeleznie kell, egyébként a minimum 13/8 MHz-es frekvencia használandó. 72 A SIM kártyán fájlrendszer található. A fájlrendszer fa-struktúrát alkot, hasonlóan egy MS-DOS-os fájlrendszerhez, ugyanígy van főkönyvtár (MF), alkönyvtárak (DF) és vannak egyszerű fájlok (EF) is. Minden fájl két részből áll, egy headerből, melyet a SIM kártya belsőleg kezel és egy opcionális body részből. A header a fájl attribútumait és szerkezeti tulajdonságait tartalmazza és a GET RESPONSE vagy a STATUS parancsok
használatával férhetünk hozzájuk. Ezen információk az adminisztrációs fázisban kerülnek véglegesítésre A body rész tartalmazza az adatokat A fájlszerkezet felépítése: Minden fájlt a „file ID” azonosít, ami két bájtból áll és hexadecimálisan kezelendő. Az első bájt adja meg a fájl típusát: - 3F: Master File - 7F: Dedicated File - 2F: Elementary File közvetlenül a Master File alatt - 6F: Elementary File egy Dedicated File alatt A „file ID” a következő tulajdonságokkal bír: - a fájl létrehozásakor kell rögzíteni - két fájlnak nem lehet azonos egyazon DF-en belül - nem lehet azonos egy, az MF-től számított elérési úton található DF „file ID”-jével A Dedicated File (DF) felel meg legjobban az általunk alkönyvtárként ismert fogalomnak. A DF kizárólag header résszel rendelkezik A GSM SIM kártyákon két kötelező DF található: - DFGSM amely a GSM és/vagy DCS1800 architektúrához szükséges
fájlokat tartalmazza - DFTELECOM amely telefonálással kapcsolatos fájlokat tartalmaz Mindkét fájl az MF közvetlen gyermeke a fa-szerkezetben. Az Elementary File (EF) felel meg az általunk egyszerűen fájlként emlegetett fogalomnak. Három féle lehet: - Transparent EF: szekvenciális adatállomány - Linear fixed EF: fix méretű rekordok halmaza 73 - Cyclic EF: szintén fix méretű rekordfájl, csak ez egy önmagába visszatérő láncolt lista több speciális tulajdonsággal Minden fájlnak minden egyes utasításra vonatkozóan jogokat lehet definiálni. A legutolsó kiválasztott fájl táblázatából minden művelet előtt kiolvassa a SIM kártya, hogy a művelet engedélyezve van-e. Minden fájl esetén: - a READ és SEEK utasításra vonatkozó jogok megegyeznek - a SELECT és STATUS utasítások esetén pedig „ALWays” Az MF-re és a DF-ekre vonatkozóan a GSM architektúra nem definiál elérési jogokat. Az elérési jogi szintek a
következők: Level Access Condition 0 ALWays 1 CHV1 2 CHV2 3 Reserved for GSM Future Use 4 to 14 ADM 15 NEVer Ezek jelentése a következő: Az utasítás ALWAYS: mindig végrehajtható korlátozás nélkül CHV1 (card holder verification 1): csak az alábbi esetekben hajtható végre: - a helyes CHV1 (=PIN1) kódot megadták a jelenlegi session alatt (azóta nem történt kártya reset) - a CHV1 bekapcsolt/kikapcsolt indikátor a „kikapcsolt” állapotban van - UNBLOCK CHV1 művelet (PUK1 kód megadása) lett végrehajtva a jelenlegi session alatt CHV2: csak az alábbi esetekben hajtható végre: - a helyes CHV2 (=PIN2) kódot megadták a jelenlegi session alatt - UNBLOCK CHV2 művelet (PUK2 kód megadása) lett végrehajtva a jelenlegi session alatt ADM: csak az adminisztrációs fázis egyes lépéseiben hajtható végre NEVER: sohasem hajtható végre, valószínűleg a SIM belsőleg kezeli a fájlt Ezek a szintek nincsenek egymással hierarchikus
viszonyban, például a CHV2 kód megadása nem engedélyez olyan műveleteket, amelyekhez CHV1 kell. 74 5.312 SIM utasítások Csak a fontosabb jellemzőket közlöm minden utasításról. Minden RFU paraméter értéke minden esetben 0. Minden utasítás osztálya (CLASS) az „A0”. Az egyes utasítások természetükből adódóan csak bizonyos típusú fájlokon hajthatók végre. Erről tájékoztat az alábbi táblázat Következzenek az utasítások, majd azután megtalálható, hogy milyen értékkel tér vissza az adott utasítás után a GET RESPONSE parancs. A táblázatban található értékek hexadecimálisak COMMAND Select Status Read Binary INS A4 F2 B0 Update Binary D6 Read Record B2 Update Record DC Seek Increase Verify CHV A2 32 20 P1 00 00 offset high offset high rekord száma rekord száma 00 00 00 Change CHV 24 00 Disable CHV Enable CHV Unblock CHV 26 28 2C 00 00 00 Invalidate Rehabilitate Run GSM Algorithm 04 44 88 00 00 00 P2 00 00
offset low P3 02 hossz hossz PARAMÉTER file ID - offset low hossz adatok mód hossz - mód hossz adatok mód 00 CHV száma CHV száma 01 01 CHV1:00 CHV2:02 00 00 00 hossz 03 08 minta érték PIN kód 10 régi és új PIN kód 08 08 10 PIN kód PIN kód PUK kód és új PIN kód 00 00 10 RAND 75 Sleep Get Response Terminal Profile Envelope Fetch Terminal Response FA C0 10 C2 12 14 00 00 00 00 00 00 00 00 00 00 00 00 00 hossz hossz hossz hossz hossz terminál profile adatsztring válasz adatsztring SELECT Fájl kiválasztása. Visszatérési érték MF vagy DF után: Offset 1-2 3-4 5-6 7 8-12 13 14 15 16 17 18 19 20 21 22 23 24-34 Leírás RFU A DF rendelkezésére álló, gyermek EF-ek vagy DF-ek által nem allokált memória nagysága File ID Fájl típusa RFU Hány bájt van még ezután (14-től az utolsóig) Fájl karakterisztika Közvetlen DF-ek száma Közvetlen EF-ek száma Adminisztratív és azonosító kódok száma RFU CHV1 státusz UNBLOCK
CHV1 státusz CHV2 státusz UNBLOCK CHV2 státusz RFU Adminisztratív információk Hossz 2 2 2 1 5 1 1 1 1 1 1 1 1 1 1 1 ? Az egyes CHV kódok státusza a következő: bit7: 1 - aktív 0 - inaktív bit6-4: RFU bit3-0: hány próbálkozás maradt Visszatérési érték EF után: Offset 1-2 3-4 5-6 7 8 Leírás RFU Fájl méret (Transparent EF: teljes méret, rekord EF: rekordméret * rekordok száma File ID Fájl típusa Ciklikus EF: bit7=1 esetén az INCREASE engedve, 76 Hossz 2 2 2 1 1 9-11 12 13 14 15 más EF: RFU Elérési jogosultságok Fájl státusz Hány bájt van még ezután (14-től az utolsóig) EF szerkezete Rekordméret, nem rekord EF-nél 00 3 1 1 1 1 STATUS Az aktuális alkönyvtárról szóló információval tér vissza. Minden visszatérő adat megegyezik a SELECT-nél leírtakkal. READ BINARY Az aktuális transparent EF-ből olvas be a P3-ban definiált mennyiségű adatot. A beolvasást a P1-P2 által megadott word-től kezdve végzi UPDATE BINARY Az
aktuális transparent EF tartalmát módosítja a P1-P2-ben megadott címtől kezdődően P3 hosszan. READ RECORD Egyetlen megadott rekord beolvasása az aktuális lineáris vagy ciklikus rekord EF-ből. 4-féle mód definiált: CURRENT: Az aktuális rekord beolvasása, a rekordmutató nem változik. ABSOLUTE: Az adott rekordszámú rekord beolvasása, a rekordmutató nem változik. NEXT: A rekordmutató megnövelése, és az aktuális rekord beolvasása. Ha nincs még aktuális rekord, akkor az elsőt olvassuk be, ha az aktuális már az utolsó rekord, semmi nem történik, ciklikus esetben ilyenkor is az elsőt olvassuk be. PREVIOUS: A rekordmutató csökkentése, és az aktuális rekord beolvasása. Ha nincs még aktuális rekord, akkor az utolsót olvassuk be, ha az aktuális már az első rekord, semmi nem történik, ciklikus esetben ilyenkor is az utolsót olvassuk be. P2 paraméter adja meg a módot: - 02 = next - 03 = previous - 04 = absolute/current, ahol P1 adja meg a
rekord számát, 0 esetén az aktuális rekord UPDATE RECORD Egyetlen megadott rekord kiírása az aktuális lineáris vagy ciklikus rekord EF-be. Az előzőhöz hasonlóan 4-féle mód definiált. SEEK Az aktuális lineáris fix rekord EF-et keresi végig annak érdekében, hogy megtalálja a megadott mintával kezdődő rekordot. Két típusa ismert: 1. típus: A rekordpointer módosítása, hogy a keresett mintának megfelelő rekordra mutasson. 77 2. típus: A rekordpointer módosítása, hogy a keresett mintának megfelelő rekordra mutasson, és visszatérési érték a rekord száma. A megadott minta 1-től 16 bájt méretű lehet, de nem haladhatja meg a rekord hosszát. Négy keresési módja van: - elejétől - végétől - következő (elejétől, ha a rekordmutató nem definiált) - előző (végétől, ha a rekordmutató nem definiált) P2 paraméter adja meg a típust és a módot: - x0 = elejétől - x1 = végétől - x2 = következő - x3 = előző
ahol az x=0 esetén 1. típusú, x=1 esetén 2 típusú a keresés INCREASE Hozzáadja az adott 3 bájtos értéket az utoljára módosított rekordhoz az aktuális ciklikus EF-ben, és az értéket a legrégebbi rekord helyére másolja, így ez lesz a legújabb rekord, és a rekordmutatót is erre állítja. A művelet nem hajtódik végre túlcsordulás esetén Visszatérési érték a megnövelt érték és az érték, amivel megnöveltük. VERIFY CHV Összehasonlítja a megadott PIN kódot a SIM kártyán lévővel. Nem lehet összehasonlítani, ha a CHV kikapcsolt állapotban van A megadott kód 8 jegyű, a nem használt számjegyek értéke „FF”. Akkor van erre az utasításra szükség, ha bizonyos fájlok PIN kóddal védettek, akkor a fájlműveletek előtt szükség van erre a műveletre. Ha a megadott PIN kód helyes, akkor a CHV számláló visszaállítódik az eredeti értékére (3). Ha a megadott PIN kód helytelen, akkor a CHV számláló értéke eggyel csökken.
3 sikertelen próbálkozás után a kártya blokkolódik CHANGE CHV Új CHV kód megadása, ha az nincs kikapcsolt állapotban. Előbb a régi, majd az új PIN kódot kell megadni. Ha a megadott PIN kód helyes, akkor a CHV számláló visszaállítódik az eredeti értékére (3). Ha a megadott PIN kód helytelen, akkor a CHV számláló értéke eggyel csökken. 3 sikertelen próbálkozás után a kártya blokkolódik DISABLE CHV Kikapcsolja a PIN-ellenőrzést. Csak a CHV1-re lehet használni. Ezután a védett állományok is bármikor elérhetők A kikapcsoláshoz meg kell adni a helyes PIN kódot. Ha a megadott PIN kód helyes, akkor a CHV számláló visszaállítódik az eredeti értékére (3). 78 Ha a megadott PIN kód helytelen, akkor a CHV számláló értéke eggyel csökken. 3 sikertelen próbálkozás után a kártya blokkolódik ENABLE CHV Bekapcsolja a PIN-ellenőrzést. Csak a CHV1-re lehet használni. Ezután a védett állományok eléréséhez újra szükséges
a kód megadása. A bekapcsoláshoz meg kell adni a helyes PIN kódot Ha a megadott PIN kód helyes, akkor a CHV számláló visszaállítódik az eredeti értékére (3). Ha a megadott PIN kód helytelen, akkor a CHV számláló értéke eggyel csökken. 3 sikertelen próbálkozás után a kártya blokkolódik UNBLOCK CHV A blokkolt kártya feloldása a PUK kóddal. Bármikor végrehajtható attól függetlenül, hogy a kártya blokkolva van-e vagy sem. Ha a megadott PUK kód helyes, akkor az UNBLOCK CHV számláló és a CHV számláló visszaállítódik az eredeti értékére (10 és 3). Ha a megadott PUK kód helytelen, akkor az UNBLOCK CHV számláló értéke eggyel csökken. 10 sikertelen próbálkozás után a kártya tartalma megsemmisül Először kell megadni a 8 bájtos PUK kódot, majd az új PIN kódot. INVALIDATE Érvényteleníti az aktuális EF-et (a megfelelő flag átállítódik). Az érvénytelenített fájl nem elérhető ezután csak a SELECT és a REHABILITATE
számára. REHABILITATE Újraérvényesíti az aktuális EF-et (a megfelelő flag átállítódik). RUN GSM ALGORITHM A SIM kártya azonosítása a GSM hálózat felé oly módon, hogy a megadott 16 bájtos véletlenszámot (RAND) kódolja a kártya a belső titkos kulccsal (Ki), amit csak a GSM hálózat ismer. Ez alapján végzi az azonosítást A művelet számos más dolgot is beállít, de csak azután hajtható végre, hogy megadtuk a PIN kódot, és kiválasztottuk a DFGSM alkönyvtárt. A megadott bemeneti állomány a 16 bájtos egész szám, a visszatérési érték a 4 bájtos SRES és a 8 bájtos Kc kulcs, melyek az adótoronnyal való kommunikáció titkosításához szükségesek. SLEEP A GSM korábbi verziójának, a Phase 1-nek az idejéből visszamaradt utasítás. Ma már nem használatos. GET RESPONSE A SIM kártya bármely utasítása után végrehajtható, a kártya és az adott fájl állapotáról szóló információk kérdezhetők le vele. A formátum
megegyezik a SELECT-nél megismerttel TERMINAL PROFILE Az ME a saját maga által támogatott funkciókról küld üzenetet a SIM kártyának ezzel. ENVELOPE 79 A SIM kártyán a SIM Application Toolkit alkalmazás számára adatok továbbítása. Input: adatsztring, output: 1 - 16 bájtnyi visszajelzés. FETCH A SIM Application Toolkit parancsot küld a ME-nek. Visszatérési érték: SIM Application Toolkit parancsot tartalmazó adatsztring. TERMINAL RESPONSE Válasz a FETCH-re az ME-től a SIM kártyának. EGYES PARAMÉTEREK: EF szerkezete: - 00 transzparens - 01 lineáris fix méretű - 03 ciklikus EF típusa: - 00 RFU - 01 MF - 02 DF - 04 EF EF státusz: - bit1=0: érvénytelen (invalidated), bit1=1: érvényes - bit2: RFU - bit3=0: ha érvénytelen, akkor nem olvasható/írható, bit3=1: ha érvénytelen, akkor is írható/olvasható CHV kódok (PIN) és UNBLOCK CHV kódok (PUK vagy Secure PIN): A kódok megadása 8 bájtos karaktersztringként történik. Kizárólag
számjegyek (0-9) adhatók meg, és a számjegyek az ASCII karakterkészlethez hasonlóan, a GSM 3.38-nak megfelelően a „30” és „39” hexadecimális intervallumban találhatók. A kód minimálisan 4, maximum 8 számjegyű Ha 8-nál kevesebb számjegyet kell megadni, akkor a maradékot az ME (telefonkészülék) az érvénytelen („FF”) értékkel tölti ki A PUK kód mindig pontosan 8 jegyű. Jogosultsági szintek: A jogosultsági szinteket a EF 9-11 bájtjai jelzik. Minden utasítástípusnak 4 bit felel meg, melyek a következők: Jogosultság Érték ALW 0 CHV1 1 CHV2 2 RFU 3 ADM 4 ADM E NEV F 80 9. bájt, bit0-bit3: UPDATE 9. bájt, bit4-bit7: READ, SEEK 10. bájt, bit0-bit3: RFU 10. bájt, bit4-bit7: INCREASE 11. bájt, bit0-bit3: INVALIDATE 11. bájt, bit4-bit7: REHABILITATE 5.313 Visszatérési értékek Az ETSI meghatározza, hogy a visszatérési értékek utolsó két bájtja a státuszbájt (SW1SW2). Ettől némileg eltérően az
ScardServer a státuszbájttal az első két helyen tér viszsza, mivel így egy fix pozíciót kell figyelnünk, ami megkönnyíti a dolgunkat Ezekkel a státuszértékekkel szeretnék foglalkozni most. Habár már az ISO szabvány is meghatározott bizonyos státuszértékeket, az ETSI kifejezetten a GSM architektúrában található státuszértékeket definiálja. A visszatérési adatokra az egyes fájlok vizsgálata közben fogok rátérni. SW1 SW2 Leírás 90 00 Normális befejeződés 91 XX Normális befejeződés, de XX hosszúságú adat még kiolvasásra vár ‘9F’ ‘XX’ - length ‘XX’ of the response data 9F XX XX hosszúságú a visszatérési adatblokk 93 00 SIM kártya foglalt. Jelenleg az utasítást nem lehet végrehajtani 92 0X Sikeres végrehajtás, de csak a X újrapróbálkozás után 92 40 Memóriahiba 94 00 Nincs EF kiválasztva 94 02 Hibás címmező 94 04 fileID/minta nem létezik 94 08 A fájlon az utasítás nem hajtható végre 98 02 CHV nincs
inicializálva 98 04 - CHV nincs megadva - Hibás a megadott CHV - Hibás a megadott UNBLOCK CHV - Hibás autentikáció 98 08 CHV nem elérhető 98 10 INVALIDATE státusz nem megfelelő 98 40 - Hibás a megadott CHV, kártya blokkolódott - Hibás a megadott UNBLOCK CHV, kártya leállt 98 50 INCREASE nem végrehajtható, érték a maximumon (Régebbi (Phase 1) SIM kártya esetén: harmadik sikertelen CHV vagy 10. sikertelen UNBLOCK CHV) 67 XX P3 nem megfelelő 6B XX* P1 vagy P2 nem megfelelő 6D XX* Ismeretlen utasításkód (INS) 6E XX* Hibás utasításosztály (CLA) 6F XX* Egyéb technikai probléma * Az ISO/IEC definiálja az „XX” értékét, jelenleg egyedül a „00” értelmezett. 81 5.314 Fájlszerkezet A GSM SIM kártya az alábbi kívülről is elérhető fájlokat tartalmazza. Emellett még egyéb fájlokat is tartalmazhat, de azokat a szabvány nem határozza meg, azokat egyedi alkalmazások használják. 82 Az ábrából kiderül a fájlok hierarchiája.
Minden blokk felső részén a fájl rövidített neve található, az alsó részén a fájl tényleges azonosítója. Következzen egy összefoglaló táblázat a fájlstruktúráról: (A Köt. az, hogy a fájl jelenléte kötelező (K), vagy opcionális(O), M a fájl mérete szekvenciális EF vagy egy rekord mérete rekord EF esetén (bájt), a Típ. pedig a fájl típusa (T=transzparens, L=lineáris fix, C=ciklikus fix)) File ID 3F00 2FE2 7F10 6F3A Név Köt. MF K EFICCID K DFTELECOM K EFADN O 6F3B 6F3C 6F3D EFFDN EFSMS EFCCP O O O 6F40 6F42 6F43 6F44 6F49 EFMSISDN EFSMSP EFSMSS EFLND EFSDN O O O O O 6F4A EFEXT1 O 6F4B 6F4C 7F20 6F05 6F07 6F20 6F30 EFEXT2 EFEXT3 DFGSM EFLP EFIMSI EFKC EFPLMNsel O O K K K K O 6F31 6F37 6F38 6F39 6F3E 6F3F 6F41 6F45 6F46 6F48 EFHPLMN EFACMmax EFSST EFACM EFGID1 EFGID2 EFPUCT EFCBMI EFSPN EFCBMID K O K O O O O O O O 6F74 6F78 6F7B 6F7E EFBCCH EFACC EFFPLMN EFLOCI K K K K M. Típ Fájl feladata - Gyökérkönyvtár 10 T
Sorozatszámot tartalmazza - Telecom könyvtár n + 14 L Rövidített telefonszámokat tartalmazó fájl n + 14 L Saját számokat tartalmazó fájl 176 L Rövid szöveges üzenetek 14 L ME által használt konfigurációs paraméter n + 14 L MSISDN rekordok n + 28 L SMS fejléc tárolása n+2 T SMS státusz információk n + 14 C Utoljára hívott számok n + 14 L Szolgáltatóközpont speciális telefonszámai 13 L ADN, MSISDN, LDN számok folytatása 13 L FDN számok folytatása 13 L SDN számok folytatása GSM könyvtár 1-n T Megadott nyelvek prioritása 9 T IMSI 9 T Ciphering key 24-3n T Mobile Country Code (MCC) és Mobile Network Code (MNC) prioritások 1 T HPLMN keresés ennyi időnként 3 T Összes hívásidő (ACM) 2T SIM kártyán implementált funkciók 3 C Aktuális hívásidő 1-n T Csoport1 azonosító 1-n T Csoport2 azonosító 5 T Egységnyi díj 2n T Celluláris üzenetközvetítési igények 17 T Szolgáltató azonosítója 2n T Igényelt celluláris
üzenetközvetítés típusok 16 T BCCH információk 2 T ACC információk 12 T 4 tiltott PLMN 11 T Területi információk 83 6FAD 6FAE 6FB1 6FB2 6FB3 EFAD EFPhase EFVGCS EFVGCSS EFVBS K K O O O 3+n 1 4n-50 7 4n-50 T T T T T 6FB4 6FB5 6FB6 6FB7 6F50 EFVBSS EFeMLPP EFAAeM EFECC EFCBMIR O O O O O 7 2 1 3-15 4n T T T T T Adminisztratív információk SIM generáció száma Igényelt Voice Group szolgáltatások Aktivált VGCS-ek státusza Igényelt Voice Broadcast szolgáltatások Aktivált VBS-ek státusza Enhanced MLPP paraméterek Automatikus válasz eMLPP-re Sürgősségi telefonszámok Igényelt celluláris üzenetközvetítés témakörök Az imént felsorolt fáljok közül néhány fontosabbat külön jellemeztem is. EFICCID (ICC Identification) Egyetlen fájl található közvetlenül az MF-en belül, mégpedig a SIM kártya egyedi sorozatszámát tartalmazó fájl. Műveletek: READ UPDATE INVALIDATE REHABILITATE ALWAYS NEVER ADM ADM 10 bájt a mérete, 19 vagy
20 számjegyet tartalmaz BCD kódolt formában, megcserélve. Ha csak 19 számjegyet tartalmaz, akkor az utolsó fél bájt „F”. A számjegyek az alábbi táblázatnak megfelelően helyezkednek el: 1. bájt 2. bájt bit7-bit4 bit3-bit0 bit7-bit4 bit3-bit0 2. jegy 1. jegy 4. jegy 3. jegy 9. bájt 10. bájt bit7-bit4 bit3-bit0 bit7-bit4 bit3-bit0 18. jegy 17. jegy 20. jegy 19. jegy EFIMSI (IMSI) A GSM könyvtárban található és az International Mobile Subscriber Identity-t tartalmazza, ennek segítségével azonosítja a számlatulajdonost a mobilhálózat. Műveletek: READ UPDATE INVALIDATE REHABILITATE CHV1 ADM ADM CHV1 9 bájt a mérete, az első bájt tartalmazza, hogy hány bájtot felhasználva tárolja a SIM kártya az IMSI-t (önmagát nem beleértve), a második bájt formátuma: bit7 bit6 bit5 bit4 első számjegy 84 bit3 bit2 bit1 bit0 paritás 0 0 1 A többi bájton az ICCID-nél megszokott módon, a számjegyek BCD kódolva,
felcserélve helyezkednek el. Ha 15-nél kevesebb számjegyet tartalmaz, akkor a maradék fél bájtok értéke „F” lesz EFSPN (Service Provider Name) A GSM könyvtárban található és a rádiótelefon-szolgáltató azonosítóját tartalmazza, ha implementálva van. Műveletek: READ UPDATE INVALIDATE REHABILITATE ALWAYS ADM ADM ADM 17 bájt a mérete, az első bájt tartalmazza, hogy szükséges-e kiírni a regisztrált PLMN-t: bit0=1 szükséges, bit0=0 nem szükséges kiírni A 2. bájttól kezdődően a szolgáltató nevét tartalmazza: balra igazított karaktersorozatként, a 7 bites GSM ABC-t használva (8 bit mindig 0), nem használt karakterek értéke „FF” EFADN (Abbreviated dialling numbers) A TELECOM könyvtárban található és a SIM kártyán a tulajdonképpeni telefonkönyvet tartalmazó lineáris, fix méretű rekord EF. Minden rekord tartalmazza egy nevet és egy telefonszámot. Műveletek: READ UPDATE INVALIDATE REHABILITATE CHV1 CHV1 CHV2 CHV2 A
rekordok mérete SIM kártyánként változó lehet, mindannyian megegyeznek azonban abban, hogy a rekordok formátuma a következő: Bájt 1-től X-ig X+1 X+2 X+3-tól X+12-ig X+13 X+14 Leírás Név azonosító Számjegyek száma Telefonszám típusa Telefonszám sztring CCP rekord azonosító Extension1 rekord azonosító Köt. O K K K Méret X 1 1 10 K K 1 1 - Név azonosító: A telefonszámhoz tartozó név, balra igazítva, a használaton kívüli bájtok értéke „FF”. A GSM 03.38 szerinti 7-bites ABC szerint van kódolva, a 8 bit 0 A táblázatban megadott X értéke 0 és 241között változik. Pontos meghatározása a GET RESPONSE művelettel lehetséges (rekordméret). - Számjegyek száma: A Telefonszám típusa és a Telefonszám sztring mezők értékes adatot tartalmazó 85 bájtjainak száma. A maximum értéke 11, ha mégis több bájtra lenne szükség, akkor az Extension1 rekord azonosítóban lévő EFEXT1-beli rekord tartalmazza a folytatást. -
Telefonszám típusa (TON, NPI): Telefonszám típusa (Type of number) és a kódolási azonosító (Numbering plan identification). Akkor lehet az értéke FF, ha a rekord nem tartalmaz telefonszámot. Bit7: 1 Bit4-Bit6: TON Bit0-Bit3: NPI A GSM hálózatban általában: TON=001, NPI=0001 - Telefonszám sztring: Maximum 20 jegyű, kiterjesztett BCD kódolt (néhány extra karakterrel), a számjegyek fel vannak cserélve. Ha 20-nál több jegyre van szükség, akkor az Extension1 rekord azonosítóban lévő EFEXT1-beli rekord tartalmazza a folytatást. 20-nál kevesebb jegy esetén az utolsó bit 4-esek értéke „F” - CCP (Capability/Configuration Parameter) azonosító: Az EFCCP-beli rekord azonosítója. A CCP a különleges hívások konfigurálására, paramétereinek beállítására szolgál A nem használt értéket az „FF” jelzi - Extension1 rekord azonosító: A felhasznált EFEXT1-beli rekord azonosítója. Az a rekord tartalmazza az ebbe a rekordba be nem
férő számjegyeket A nem használt értéket az „FF” jelzi Egy SEEK parancs végrehajtása közben figyelni kell arra, hogy nehogy az X-nél nagyobb értékkel adjuk ki a SEEK parancsot! Kiterjesztett BCD táblázat: Karakter 0 9 A B C D E F Leírás 0 9 * # DTMF Control elválasztó (3 sec szünet) Input mező (számjegyet a felhasználó írja be) Shift (a következő számjegy értékét „10” hexa értékkel megnöveli) Lezáró (ha fél bájt üresen maradt) EFFDN (Fixed dialling numbers) A TELECOM könyvtárban található és a saját számokat tartalmazó lineáris, fix méretű rekord EF. Műveletek: READ UPDATE INVALIDATE REHABILITATE CHV1 CHV2 ADM ADM Mindenben megegyezik a Rövid telefonszámokat tartalmazó rekord formátumával (bár az itteni X eltérhet az ottanitól), egyetlen kivételtől eltekintve, miszerint itt az Extension1 helyett az Extension2 használatos. 86 EFSMS (Short messages) A TELECOM könyvtárban található és a rövid szöveges
üzeneteket tartalmazó lineáris, fix méretű rekord EF. Műveletek: READ UPDATE INVALIDATE REHABILITATE CHV1 CHV1 ADM ADM Minden rekord 176 bájt méretű. Az első bájt az üzenet státuszát jelöli: bit3-bit7: RFU, a 0-2. bitek jelentése a következő: Bit2 0 0 0 1 1 Bit1 0 0 1 0 1 Bit0 0 1 1 1 1 Leírás üres rekord olvasott üzenet új, olvasatlan üzenet elküldött üzenet tárolt üzenet A 2-176 bájtok tartalmazzák az üzenetet magát. Az adatblokk a GSM 0411-ben definiált TS-Service-Centre-Address mezővel kezdődik ezt a GSM 0340 szabvány szerint definiált Short message TPDU követi, melynek formátumát lásd a későbbiekben Tehát a rekord szerkezete: 1. bájt státusz (GSM 11.11) 2. bájt x bájt TS-SC Address (GSM 04.11) x+1. bájt 176 bájt Transfer Protokol Data Unit (GSM 03.40) 5.32 GSM 0411 A GSM 04.11 a „Digital cellular telecommunications system (Phase 2+); Point-to-Point (PP) Short Message Service (SMS) support on mobile radio interface”
címet viseli, amely magyarul kb. annyit jelent, hogy a digitális celluláris telekommonikációs rendszerek SMS (rövid szöveges üzenetek) szolgáltatásának megvalósítása a rádiótelefonokon definíciója Részletesebben nem kívánok ezzel a szabvánnyal foglalkozni, csak nagy vonalakban mutatom be az SMS adatblokkhoz kapcsolódó részeket. Általános működési elv A mobiltelefonok kommunikációja különböző logikai szintekre bontható fel. A kommunikáció egyetlen alkalmazási módja csupán az SMS szolgáltatás Az SMS szolgáltatás üzenetek továbbítását teszi lehetővé több GSM PLMN Mobile Station (MS - telefonkészülék) között a Service Centre (SC - szolgáltató-központ) segítségével. A következő kifejezések „MO” - Mobile Originating és „MT” - Mobile Terminating arra utalnak, hogy az üzenet melyik irányból érkezett az MS és az SC között. Elég ezt a felületet definiálni, hiszen két MS közötti kapcsolat felfogható egy
MSSC és egy fordított irányú MS-SC kapcsolataként, sőt a valóságban is két ilyen kapcsolat megteremtésével jön létre a „látszólagos” MS-MS kapcsolat 87 A rétegek elhelyezkedése látható az alábbi ábrán: CM-sublayer: szolgáltatásokat nyújt a Short Message Relay Layer felé Az MS oldalon a Short Message Relay Layer szolgáltatásokat nyújt a Short Message Transfer Layer felé, míg az SC oldalon a legfelső rétegként a Short Message információkat egy TCAP/MAP formátumú adatblokká alakítja. Két SMC entitás közötti információcsere protokollja az SM-CP, két SMR entitás közöttié pedig az SM-RP. Rövidítések: SM-AL: Short Message Application Layer SM-TL: Short Message Transfer Layer SM-RL: Short Message Relay Layer SM-RP: Short Message Relay Protocol SMR: Short Message Relay (entitás) CM-sub: Connection Management sublayer SM-CP: Short Message Control Protocol SMC: Short Message Control (entity) MM-sub: Mobility Management sublayer
RR-sub: Radio Resource Management sublayer Ezen a szinten a legmagasabb alkalmazott protokoll az RP. A SIM kártyán azonban még egy ennél is magasabb szintű protokoll, a TP szerint tárolódnak az adatok, így az RP fejlécből nem sok információt láthatunk. Ezen kivételek egyike az RP-Originator Address, amely MT esetben a származási Service Centre címét tartalmazza. A mező formátuma az alábbi: Bit7 1 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 A teljes RP-Originator Address Element hossza Type of Number Numbering Plan Identification 2. jegy 1. jegy 4. jegy 3. jegy A hossz mezőbe saját maga nem számít bele, így a minimális értéke a hossz mezőnek 2, a maximum értéke pedig 11. MO esetben a hossz mező értéke 0 Ha az RP-Originator Address páratlan számjegyből áll, akkor az utolsó fél bájt értéke „F”. 88 Minden SMS rekord adatblokkjának első néhány bájtja az imént definiált RP-Originator Address. 5.33 GSM 0340 A GSM 03.40 a „Digital
cellular telecommunications system (Phase 2+); Technical realization of the Short Message Service (SMS) Point-to-Point (PP)” címet viseli, amely magyarul kb. annyit jelent, hogy a digitális celluláris telekommonikációs rendszerek SMS (rövid szöveges üzenetek) szolgáltatásának technikai megvalósítása definíciója. A szabvány bizonyos témaköreivel részletesen foglalkozom, amelyek az SMS adatblokk felépítését tárgyalják. 5.331 Általános működési elv A két pont közötti SMS-kommunikáció két egyszerűbb lépésre bontható, a szabvány ezen egyszerűbb lépések meghatározásával foglalkozik. A két lépés: - SM MO (Short Message Mobile Originated - telefon felől a központ felé) - SM MT (Short Message Mobile Terminated - központ felől a telefon felé) Az SM MO esetén a GSM rendszerben az MS által létrehozott szöveges üzenet az SC felé halad, majd a SC egy válasz „report”-ban visszajelez a kézbesítésről vagy valamely
hibáról. Az üzenetnek tartalmaznia kell a célállomás címét, ahová az SC kézbesíteni tudja az üzenetet. Az SM MT esetén a GSM rendszerben az SC által kézbesített szöveges üzenet az MS felé halad, majd az MS egy válasz „report”-ban visszajelez a kézbesítésről vagy valamely speciális felmerülő hibáról. Természetesen az SMS szolgáltatás nem ilyen egyszerű, de a technikai részletekbe bonyolódás nélkül nagyjából ez a lejátszódó folyamatok sémája. Egy működő MS-nek állandóan készen kell állni arra, hogy egy rövid szöveges üzenet TPDU-t fogadjon (SMS-DELIVER), még akkor is, ha épp beszélgetés vagy adatküldés van folyamatban. Erre az MS-nek válaszolnia is kell (report) a SC felé, vagy arról, hogy fogadta az üzenet, vagy tájékoztatnia kell arról, hogy mely okból volt képtelen az üzenetet fogadni. Egy működő MS-nek képesnek kell lennie arra, hogy egy rövid szöveges üzenet TPDUt küldjön (SMS-SUBMIT) bármely
esetben, még akkor is, ha épp beszélgetés vagy adatküldés van folyamatban. Ezután fogadni a kell a választ (report) arról, hogy az SC fogadta az üzenetet, vagy arról, hogy az SC miért nem fogadta azt. Lehetséges két üzenetet fogadni egymás után ugyanazzal az azonosítóval, küldő központ címével vagy időbélyegzővel is. Ekkor a fogadó entitás feladata annak eldöntése egyéb paraméterek megvizsgálásával, hogy két külön üzenetről van szó, vagy egyazon üzenet érkezett duplán valamely RP vagy CP réteg hiba miatt. 89 5.332 Short Message elemek Az SMS szolgáltatás 7 különböző elemet tartalmaz az üzenetek fogadása és küldése kapcsán: - Validity-Period: Érvényességi idő - Service-Centre-Time-Stamp: Szolgáltató központ időbélyegzője - Protocol-Identifier: Protokoll azonosító - More-Messages-to-Send: További üzenetek várnak kézbesítésre - Priority: Elsőbbség - Messages-Waiting: Várakozó üzenet -
Alert-SC: Figyelmeztetés Validity-Period: A Validity-Period értékét az MS adja meg az SC felé az SMS-SUBMIT által annak TP-Validity-Period mezőjében. A TP-Validity-Period paraméter azt az időt tartalmazza, amíg az üzenet érvényes, azaz kézbesíthető Service-Centre-Time-Stamp: A Service-Centre-Time-Stamp az az információegység, melyben a SC értesíti az MS-t az üzenet érkezésének idejéről. Az időpont minden SMS-DELIVER-ben a TP-Service-Centre-Time-Stamp mezőben elküldésre kerül. Protokol-Identifier: A Protocol-Identifier az az információegység, melyben az SM-TL réteg a felette levő réteg protokolljának használatát jelzi, vagy Telematic Interworking-et (lásd később!) jelez. More-Messages-to-Send: A More-Messages-to-Send az az információegység, melyben az SC tudatja az MSsel, hogy még legalább egy üzenet vár kézbesítésre. Az SMS-DELIVER-ben egy boolean értékként jelenik meg. Priority: A Priority az az információegység, melyben az
SC jelzi, hogy az üzenetnek elsőbbsége van. Ekkor az üzenet továbbítását a SC akkor is megpróbálja, ha az MS átmenetileg nem elérhető, vagy a memóriája megtelt Messages-Waiting: A Messages-Waiting az az információegység, melyben a GSM hálózat (PLMN) egyes egységei jelzik, hogy az SC nem tudta az üzenetet továbbítani az MS felé. Alert-SC: Az Alert-SC az az információegység, melyben a GSM hálózat informálja az SC-t, hogy egy MS 1) mely számára nem sikerült egy üzenet továbbítani, mert az MS nem elérhető vagy betelt a memóriája és 2) amelyet most a hálózat felismert: a) újra működik vagy b) újra van elérhető memóriája 90 újra kész arra, hogy fogadjon egy vagy több üzenetet. Ennek hatására az SC újra próbálkozik az üzenet küldésével. 5.333 Adatblokk mezők Alfanumerikus reprezentáció Bizonyos adatblokk mezők alfanumerikus karakterkészlettel vannak ábrázolva, ami azt jelenti, hogy a GSM 03.38-ban definiált 7 bites
karakterkészlettel vannak ábrázolva Ha nincs külön megadva, hogy a 8. bit (bit7) 0 értékű, akkor előfordulhat, hogy a nyolcadik bit már a következő karakter első bitje, ekkor a második bájtban már a 7. és 8 bit a következő karakter bitjei stb Ezzel a módszerrel van „tömörítve” az SMS adatblokk tényleges, továbbítandó üzenet része Címmező Sok helyen szerepel címmező (Address field). Ez néhány dologban eltér az RP-beli címmezőtől, ezért ezt itt külön bemutatom. Minden címmező az alábbi felépítésű: 1. 2. 3. - bájt: címhossz bájt: a Type-of-Address mező bájttól: a változó hosszúságú címérték mező Címhossz: a felhasznált bit 4-esek száma a címérték mezőben - TOA: Bit7 1 Bit6 Bit5 Bit4 Type of Number Bit3 Bit2 Bit1 Bit0 Numbering Plan Identification A Type of Number értékei: Bit6 0 0 0 0 1 1 1 1 Bit5 0 0 1 1 0 0 1 1 Bit4 0 1 0 1 0 1 0 1 Leírás Ismeretlen Nemzetközi formátum Nemzeti formátum
Hálózatspecifikus szám Előfizetői speciális Alfanumerikus Rövidített szám Fenntartva 91 - Ismeretlen: nincs információ az Numbering Plan-ről, a címérték mező ekkor a Network Dialling Plan szerint van kódolva - Nemzetközi formátum: szintén elfogadott belföldi üzeneteknél - Nemzeti formátum: előhívó és escape szekvencia nem engedélyezett - Hálózatspecifikus szám: a hálózatra jellemző adminisztrációs/szolgáltatási telefonszámok - Előfizetői speciális: több SC-ben is eltárolt telefonszám, melyet egy magasabb rétegben található alkalmazás használ A Numbering Plan Identification értékei: (A TON: 000, 001 és 010 értékei mellett) Bit3 0 0 0 0 1 1 1 Bit2 Bit1 Bit0 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 1 0 1 0 Minden más érték Leírás Ismeretlen Telefon/ISDN séma Adat séma Telex séma Nemzeti séma Magán séma ERMES séma Fenntartva TON=101 esetén az NPI=0000. Az MS visszautasíthatja azokat az üzeneteket, melyekben a TON vagy
az NPI fenntartott, vagy nem támogatott. A maximális értéke a címmezőnek: (címhossz, Type-of-Address és címérték) 12 bájt. - Címérték mező: Ez a mező tartalmazza a címbeli karaktereket a Type-of-Address szerinti formátumban. Általában a fordított BCD vagy a 7 bites alfanumerikus verzió használatos TP-Message-Type-Indicator (TP-MTI) A TP-Message-Type-Indicator egy 2-bites mező, az SMS-DELIVER és SMS-SUBMIT első bájtjának bit0-bit1 helyén. Formátuma: Bit1 0 0 1 1 0 0 1 Bit0 0 0 0 0 1 1 1 Üzenet típusa SMS-DELIVER (SCMS irány esetén) SMS-DELIVER-REPORT (MSSC irány esetén) SMS-STATUS-REPORT (SCMS irány esetén) SMS-COMMAND (MSSC irány esetén) SMS-SUBMIT-REPORT (SCMS irány esetén) SMS-SUBMIT (MSSC irány esetén) Fenntartva 92 Az SMS szolgáltatás számos üzenettípust definiál, számunkra azonban kizárólag az SMS-SUBMIT (szöveges üzenet küldése a SIM kártyáról) és az SMS-DELIVER (szöveges üzenet fogadása a
szolgáltatóközpontból) fontos. TP-More-Messages-to-Send (TP-MMS) A TP-More-Messages-to-Send egy 1-bites mező, mely a SMS-DELIVER első bájtjának bit2 helyén található. Formátuma: Bit2=0: Az SC-ben még van továbbítandó üzenet Bit2=1: Nincs továbbítandó üzenet az SC-ben TP-Validity-Period-Format (TP-VPF) A TP-Validity-Period-Format egy 2-bites mező, mely az SMS-SUBMIT első bájtjának bit3-bit4 helyén található. Formátuma: Bit4 0 1 0 1 Bit3 0 0 1 1 Leírás TP-VP mező nincs jelen TP-VP jelen van, és integer formátumú (relatív) Fenntartva TP-VP jelen van, és felcserélt BCD formátumú (abszolút) TP-Status-Report-Indication (TP-SRI) A TP-Status-Report-Indication egy 1-bites mező, mely az SMS-DELIVER 1. bájtjának bit5 helyén található. Formátum: Bit5=0: Nincs státuszvisszajelzés Bit5=1: Van státuszvisszajelzés TP-Status-Report-Request (TP-SRR) A TP-Status-Report-Request egy 1-bites mező, mely az SMS-SUBMIT 1. bájtjának bit5 helyén
található. Formátuma: Bit5=0: Nincs szükség státuszvisszajelzésre Bit5=1: Státuszvisszajelzés szükséges TP-Message-Reference (TP-MR) A TP-Message-Reference mező egy integer referencia érték az SMS-SUBMIT-on belül. Ennek segítségével lehet megoldani, hogy egy korábbi SMS-t lecserél a SIM kártya a kapott új üzenetre (pl. számlaegyenleg tipikusan ilyen) Értéke 0-tól 255-ig terjedhet. TP-Originating-Address (TP-OA) A TP-Originating-Address mező a címzett adatait tartalmazó címmező formátumú mező. A címmező formátumát lásd ennek a fejezetnek az elején, a második bekezdésben TP-Destination-Address (TP-DA) A TP-Destination-Address mező a célállomás adatait tartalmazó címmező formátumú mező. 93 TP-Protocol-Identifier (TP-PID) The TP-Protocol-Identifier egy 1-bájt méretű mező, mely megadja a használt protokollformátumot. Az MS visszautasíthatja a fenntartott vagy nem támogatott protokollformátumú üzeneteket. Bit7 0 0 1 1 Bit6
0 1 0 1 Leírás Speciális 1. változat Speciális 2. változat Fenntartva SC specifikus jelentés - Speciális 1. változat: bit5=0: nincs telematic interworking bit5=1: telematic interworking Telematic interworking esetén a többi bit jelentése a különböző telematikus eszközöket jelenti, a táblázat megtalálható a CD-mellékleten lévő GSM 03.40 szabvány 9.239 fejezetében - Speciális 2. változat: Többek között itt lehet beállítani, hogy milyen üzenetet kívánunk lecserélni a már meglevők közül a kapott új üzenetre. TP-Data-Coding-Scheme (TP-DCS) A TP-Data-Coding-Scheme paramétert a GSM 03.38 szabvány definiálja TP-Service-Centre-Time-Stamp (TP-SCTS) A TP-Service-Centre-Time-Stamp mező felcserélt BCD formátumban van megadva, a helyi időt adja meg: Év bájt6 Hó bájt5 Nap bájt4 Óra bájt3 Perc bájt2 Másodperc bájt1 Időzóna bájt0 Az időzóna a helyi idő GMT-től való eltérését adja meg negyedórákban. A bit7 értéke az
előjel (0: pozitív, 1: negatív). TP-Validity-Period A TP-Validity-Period mező vagy integer, vagy felcserélt BCD formátumban található. Integer esetén 1 bájtos és az érvényességi idő hosszát jelzi, míg a másikesetben a hossza 7 bájt az abszolút lejárati időt adja meg. TP-User-Data-Length (TP-UDL) Megadja, hogy a TP-User-Data hány karaktert tartalmaz. Ha a TP-User-Data az alapértelmezett alfanumerikus kódolással van ábrázolva, akkor a TP-User-Data-Length nem egyezik meg a TP-User-Data tényleges hosszával, mivel a karaktereket 7 biten ábrázoljuk. TP-Reply-Path (TP-RP) A TP-Reply-Path egy 1-bites mező az SMS-DELIVER és a SMS-SUBMIT első bájtjának bit7 helyén. 94 Formátuma: Bit7=0: TP-Reply-Path paraméter nincs beállítva Bit7=1: TP-Reply-Path paraméter be van állítva TP-User-Data-Header-Indicator (TP-UDHI) A TP-User-Data-Header-Indicator egy 1-bites mező az SMS-SUBMIT és az SMSDELIVER első bájtjának bit6 helyén. Formátuma: Bit6=0: A
TP-UD mezőben nincs fejléc Bit6=1: A TP-UD mező tartalmaz fejlécet TP-User Data (TP-UD) A TP-User-Data mező maximum 140 bájt hosszú lehet, a TP-UDHI-tól függően fejlécet is tartalmazhat. Az adatokat ábrázolhatjuk 7 biten (alapértelmezett), 8 biten vagy 16 biten (UCS2) Ha van fejléc, akkor az első néhány bájt a fejlécet tartalmazza, melynek formátuma: Mező Fejléc hossza „A” rész azonosító „A” rész hossza „A” rész tartalma „B” rész azonosító „B” rész hossza „B” rész tartalma „X” rész azonosító „X” rész hossza „X” rész tartalma Hossz (bájt) 1 1 1 1-n 1 1 1-n 1 1 1-n Ha nincs fejléc, akkor itt már maga az üzenet szövege található. 95 5.334 SMS-DELIVER Minden használaton kívüli bit értéke 0. Az SMS-DELIVER az az üzenetformátum, amikor a szolgáltatóköpont üzenet továbbít a felhasználó telefonkészülékére. Ilyenkor a különböző rétegek különböző protokolljainak fejlécei
leválasztása után a fenti formátumú üzenetek találhatók a SIM kártyán Példa egy SMS bejegyzésre: 0107916307996905f0040b916307526479f732003030815143800416d3a0339b040541cb273329443075a0 2048068b01 Az iménti egy SIM kártyán tárolt olvasott üzenet, amint azt az első bájtja is mutatja: 01 Ezután következik a szolgáltatóközpont azonosítója: 07916307996905f0 (hossza:7 bájt, 91=nemzetközi formátum (+), így a szám: +36709996500) A TP adatmező ezután következik. Az első bájt értéke: 04 (SMS-DELIVER, nincs további várakozó üzenet, nincs státuszvisszajelzés, nincs fejléc az üzenetben, nincs Reply-Path) Ezt követi a küldő címe: 0b916307526479f7 (hossza:11 jegy, 91=nemzetközi formátum, vagyis a szám: +36702546977) Ezután jön a protokollazonosító: 32 (Speciális 1. változat:telematic interworking-Internet Electronic Mail Bizonyos üzenetfajtákat képes csak fogadni a SIM kártya, ezt például igen, de az alapértelmezett
protokollazonosító a „00”=rövid szöveges üzenet) 96 A következő a kódolási séma: 00 (default alphabet) Ezt követi az időbélyegző: 30308151438004 (az időpont: 03.0318 15:34:08 GMT+1 óra) Ezt követi az üzenet hossza: 16 (22 karakter) Végül maga az üzenet szövege: d3a0339b040541cb273329443075a02048068b01 („SANYI A KOLIBóL: A 201”) 5.335 SMS-SUBMIT Minden használaton kívüli bit értéke 0. Az SMS-SUBMIT az az üzenetformátum, amikor a felhasználó telefonkészüléke a szolgáltatóköpont felé üzenet küld. Ha az üzenetet nem küldi el a felhasználó, hanem csak eltárolja, akkor a legtöbb helyen értelemszerűen 0 vagy „FF”=érvénytelen érték található. Nézzük meg, hogyan nézne ki az előbbi példa, ha az nem Olvasott üzenet, hanem Tárolt üzenet lenne! Példa egy SMS bejegyzésre: 0700010080000016d3a0339b040541cb273329443075a02048068b01 Ez egy tárolt üzenet, az első bájtja is mutatja: 07 Ezután következik a
szolgáltatóközpont azonosítója: 00 (hossza: 0 bájt, ezért hiányoznak a számokat reprezentáló mezők) A TP adatmező ezután következik. Az első bájt értéke: 01 97 (SMS-SUBMIT, nincs érvényességi mező, nem szükséges státuszvisszajelzés, nincs fejléc az üzenetben, nincs Reply-Path) Ezt követné a referenciaszám egy valódi SMS-SUBMIT esetén, azonban a referenciaértéknek csak elküldött üzenet esetén van értelme, így kimarad. Ezt követi a cél telefonszáma: 0008 (felhasznált jegyek a címérték mezőben: 0, TON: 08, a címérték mező hiányzik) Ezután jön a protokollazonosító: 00 (alapértelmezett protokollazonosító a „00”=rövid szöveges üzenet) A következő a kódolási séma: 00 (default alphabet) Ezt követi az üzenet hossza: 16 (22 karakter) Végül maga az üzenet szövege: d3a0339b040541cb273329443075a02048068b01 („SANYI A KOLIBóL: A 201”) 5.34 GSM 0338 A GSM 03.38 a „Digital cellular telecommunications system
(Phase 2+); Alphabets and language-specific information” címet viseli, amely magyarul kb. annyit jelent, hogy a digitális celluláris telekommonikációs rendszerek karakterkészletei és nyelvspecifikus információk definíciója. 5.341 SMS Data Coding Scheme A TP-Data-Coding-Scheme mezőt a GSM 03.40 szabvány használja a TP-UD mező ábrázolási módjának meghatározására Egy bájt méretű mező, melynek formátuma a következő: Bit7-Bit4 00xx Bit3-Bit0 Kódolási információk: Bit5=0: tömörítetlen szöveg Bit5=1: GSM szabványos tömörítési algoritmussal tömörített Bit4=0: Bit1-Bit0 fenntartott és nem használt Bit4=1: Bit1-Bit0 az üzenet osztálya: Bit1-Bit0: - 00: Class 0 - 01: Class 1 telefonspecifikus üzenet - 10: Class 2 SIM kártya specifikus üzenet - 11: Class 3 TE specifikus Bit3-Bit2: - 00: alapértelmezett ábécé - 01: 8 bites ábécé - 10: UCS2 (16bit) - 11: Fenntartott 0100.1011 1100 1101 Ha a teljes DCS bájt értéke 00000000, az az
alapértelmezett ábécét (Default Alphabet) jelenti. Fenntartott Üzenet várakozás jelző: üzenet eldobása Üzenet várakozás jelző: üzenet tárolása 98 1110 1111 5.342 Üzenet várakozás jelző: üzenet tárolása (UCS2 kódtábla) Adatkódolási osztály: Bit3: fenntartott, értéke 0. Bit2: üzenet kódolása 0: Default alphabet 1: 8-bites adat Bit1-Bit0: üzenet osztálya 00: Class 0 - 01: Class 1 telefonspecifikus üzenet - 10: Class 2 kártya specifikus üzenet - 11: Class 3 TE specifikus Karakterkészlet 1) A 0011011 kódú karakter egy escape szekvencia. Amely készülékek értelmezik a használatát, azok a következő karaktert a kiterjesztett karaktertábla szerint értelmezik, amely készülékek nem értelmezik, azok egy szóközt jelenítenek meg helyette. 99 Kiterjesztett karaktertábla Ha valamely készülék nem értelmezi az escape szekvenciát, akkor megjeleníti az azt követő karaktert az alapértelmezett tábla szerint. Ezért kell
követni azt a konvenciót, hogy a kiterjesztett karaktertábla elemei azokra a pozíciókra keüljenek, ahol az alapértelmezett táblában hozzájuk hasonló karakterek találhatók. 1) Escape szekvencia Addig szóközt jelent, amíg nem definiált egy második kiterjesztett karaktertábla. 2) euró szimbólum „€” Az „e” karakter helyén található. 3) Oldaltörés (Page Break) Az LF helyén található. 100 5.4 CSP (bővebben: http://www.microsoftcom internetcímen vagy a Microsoft Platform SDK-n) Ebben a fejezetben összegyűjtöttem azokat az információkat, amelyek segítségével rálátás nyílik a Microsoft CryptoAPI funkciókra és adattípusokra. Emellett próbáltam megvilágítani azokat a részeket, amelyeket magam is felhasználtam az elkészített programokban 5.41 Cryptographic Service Provider jellemzői Ebben a szakaszban a cryptographic service provider (CSP) interfészt és a hozzá kapcsolódó eljárásokat kívánom ismertetni. Mint korábban
is említettem a CSP-k kriptográfiai algoritmusok és szabványok implementációit tartalmazzák. A Windows eleve számos CSP entitást tartalmaz, azonban ezek mellé mi is készíthetünk sajátokat. Minden CSP tartalmaz egy dynamic-link library-t (DLL), amely számos függvényt deklarál. Számos CSP-t implementáltak legalább részben bizonyos Win32 rendszerprogramokban, melyeket a Win32 Service Control Manager kezel Emellett számos CSP a hardverbe került beépítésre, mint például intelligens kártyába ágyazva vagy titkosító koprocesszorként. Mindkét esetben a DLL arra szolgál, hogy egy átjáróként szolgáljon, egy rétegként az operációs rendszer és az aktuális CSP megvalósítása közötti kommunikációban. Amint az alábbi ábra is mutatja, a különböző alkalmazások nem közvetlenül magával a CSP-vel kommunikálnak. Ehelyett hívásokat intéznek a CryptoAPI-hoz, melynek függvényeit az operációs rendszer részeként az Advapi32dll fájl
deklarálja Az operációs rendszer lekezeli ezeket az eljáráshívásokat és továbbítja őket a megfelelő CSP felé a CryptoSPI interfészen keresztül. Az alkalmazások a különböző CSP-beli objektumokra úgynevezett „kezelők” (handles) segítségével hivatkozhatnak. Ilyen objektumok például a key container-ek, hash objectek, session key object-ek és nyilvános/titkos kulcspárok Ezek a kezelők láthatók mindkét oldalról, habár azért az alkalmazás által látott kezelők nem azonosak a CSPbeliekkel, különböző okok miatt az operációs rendszer réteg valósítja meg ezt az indirekciót. Minden CSP-hez tartozó DLL-ben meg kell valósítani a következő belépési pontokat: 101 - CPAcquireContext - CPGetProvParam - CPCreateHash - CPGetUserKey - CPDecrypt - CPHashData - CPDeriveKey - CPHashSessionKey - CPDestroyHash - CPImportKey - CPDestroyKey - CPReleaseContext - CPEncrypt - CPSetHashParam - CPExportKey - CPSetKeyParam
- CPGenKey - CPSetProvParam - CPGenRandom - CPSignHash - CPGetHashParam - CPVerifySignature - CPGetKeyParam Ezek a funkciók alkotják a CryptoSPI-t és közvetlenül megfelelnek a CryptoAPI-beli függvényeknek. A CryptoAPI egyetlen függvényt tartalmaz ezen kívül, a CryptSetProvider függvényt, amit nem továbbít a CSP-nek. Minden CSP maga felelős azért, hogy tárolja a nyilvános/titkos kulcsokat session-ről session-re valamely különálló memóriaterületen. Egy teljes mértékben szoftveresen megvalósított CSP akár a Windows Registry-ben is tárolhatja, természetesen kódolt formában. A hardveres komponensekkel megvalósított CSP-k esetén a kulcspárok tárolása valamely feltörésbiztos hardveregységben szokott történni A kulcspárokat logikai objektumokban, az úgynevezett „key container”-ekben tároljuk. A CSP egy key container-t társít minden egyes felhasználóhoz vagy klienshez, amely CSP-t kíván használni. Minden key container egy
kulcspárt tárolhat minden egyes CSP által felismerhető kulcspártípusból. Például a Microsoft Base Cryptographic Provider kétféle típusú kulcspárt ismer, a „key exchange” típust és a „digital signature” típust. Több key containers lehet „nyitva” egyidejűleg, akár több alkalmazás részéről is, de minden CryptoSPI függvényhíváshoz meg kell adni a használandó key container-t a függvény első paramétereként. Ezt próbálja érzékeltetni a következő ábra: 102 A CryptoSPI interfész szintjén a HCRYPTPROV adattípust használjuk a CSP-n belül egy adott key container kezelőjeként. Ez némileg eltér a CryptoAPI interfész szintjén, ahol a HCRYPTPROV adattípusú kezelők magát a CSP-t is meghatározzák. A CSP-k a session key object-eket és a hash object-eket a rendszermemóriában tárolják. Ezeket az objektumokat a CPGenKey és CPCreateHash funkciókkal hozhatjuk létre, valamint a CPDestroyKey és CDDestroyHash funkciókkal
szüntethetjük meg. Ezeket azelőtt kell megszüntetni, hogy a hozzájuk kapcsolódó key container-t felszabadítjuk a CPReleaseContext függvényhívás segítségével. A CryptoAPI-t úgy tervezték, hogy nagyon egyszerűen továbbfejleszthető legyen. Új típusokat és új paramétereket adhatunk meg úgy, hogy a CryptoAPI alkalmassá tehető arra, hogy bármely felmerülő igényt kielégítsen. A továbbfejlesztés lehetséges irányai: - Provider típusok: Minden egyes provider típus egy különálló family-t vagy kriptográfiai szolgáltatások egy típusát határozza meg. Sok új provider típust definiálhatunk, hogy mindegyik valamely egyedi módszert használhasson - Provider paraméterek: Ezeket az adatcsomagokat a CPSetProvParam és a CPGetProvParam segítségével küldhetjük vagy fogadhatjuk. Új paraméterek definiálásával elérhető, hogy az adott CSP-t nem szokványos, az eredeti működési módtól eltérő működésre bírjuk. - Algoritmus
azonosítók: Új szimmetrikus, nyilvános kulcsú és hash algoritmusokat adhatunk meg. A CPGetProvParam segítségével az alkalmazások dinamikusan hozzáidomulhatnak a CSP lehetőségeihez - Nyilvános/titkos kulcspár típusok: Csak a már említett kétféle kulcspár típus létezik. Ezek mellé számos másikat is definiálhatunk igényeinknek megfelelően. - Key blob típusok: Új key blob típusokat adhatunk meg, melyek segítségével lehetőség nyílik session key-ek, nyilvános kulcsok és nyilvános/titkos kulcspárok kicserélésére rugalmas módon a CPExportKey és CPImportKey függvényekkel. - Kulcs paraméterek: Ezeket az adatcsomagokat a CPSetKeyParam és a CPGetKeyParam segítségével küldhetjük vagy fogadhatjuk. Új paraméterek definiálásával elérhető, hogy több különböző féle kulcstípust támogassunk - Hash paraméterek: Ezeket az adatcsomagokat a CPSetHashParam és a CPGetHashParam segítségével küldhetjük vagy fogadhatjuk. Új
paraméterek definiálásával elérhető, hogy több különböző féle hashtípust támogassunk - Flag értékek: Minden CryptoAPI/CryptoSPI funkciónak van egy „dwFlags” paramétere. Új flageket definiálhatunk úgy, hogy minden funkció tulajdonságait a szükséges módon módosítani lehessen 103 Ha azt szeretnénk, hogy az általunk megváltoztatott CSP kompatíbilis legyen a Microsoft Base Cryptographic Provider-t használó alkalmazásokkal, akkor szükséges, hogy alaposan tanulmányozzuk a CryptoAPI referenciát. Részletes leírás található a Visual Studiohoz mellékelt Microsoft Developer Network CryptoAPI Reference Overview és RSA/Full CSP Reference Overview fejezeteiben. Létezik egy, a Microsoft Base Cryptographic Provider-nél hatékonyabb biztonságú provider, a Microsoft Enhanced Cryptographic Provider. Ez azonban nem mindenhol elérhető. Eredetileg csak az Egyesült Államokban volt használható, mára azonban az újabb verziók megjelenésével
máshol is elérhetővé vált. Ez az alkalmazások számára nagyobb fokú védelmet nyújt a titkos adataik védelmében. A következő táblázat foglalja össze az alap és továbbfejlesztett verziók különbségeit: Algoritmus RSA Key Exchange RSA Signature RC2 RC4 DES Triple DES (2-key) Triple DES (3-key) MS Base Provider 512-bit 512-bit 40-bit 40-bit Nem implementált Nem implementált Nem implementált MS Enhanced Provider 1024-bit 1024-bit 128-bit 128-bit 56-bit 112-bit 168-bit 5.42 CSP függvények Az alábbi Win32 kriptográfiai funkciók valósítják meg a kommunikációt a kívánt cryptographic service provider-rel (CSP). Ezek a funkciók a Wincrypth header fájban kerülnek deklarálásra. Funkció Leírás Az adott CSP-n belül egy meghatározott key containerCryptAcquireContext hez egy kezelőt társít. Egy HCRYPTPROV-ra vonatkozó referenciaszámlálót CryptContextAddRef növel meg. CryptCreateHash Inicializál egy hash függvényt egy sztringre. Egy
előzőleg a CryptEncrypt függvénnyel kódolt adatCryptDecrypt blokk visszaállítása. CryptDeriveKey Kulcs előállítása a megadott adatokból. A hHash paraméter által meghatározott hash objektum CryptDestroyHash megsemmisítése. A hKey paraméter által meghatározott kulcs megsemmiCryptDestroyKey sítése. CryptDuplicateHash Egy hash-ről és az állapotáról másolat készül. CryptDuplicateKey Egy kulcsról és az állapotáról másolat készül. CryptEncrypt Adatblokk kódolása. CryptEnumProviders Providerek felsorolása az adott számítógépen. CryptEnumProviderTypes Providertípusok felsorolása az adott számítógépen. CryptExportKey Kulcsok CSP-n kívülre másolása. CryptFormatObject A kódolt adatok formátumának beállítása. CryptGenKey Véletlen kulcs előállítása. CryptGenRandom Memóriablokk feltöltése véletlen értékekkel. 104 CryptGetDefaultProvider CryptGetHashParam CryptGetKeyParam CryptGetProvParam CryptGetUserKey CryptHashData
CryptHashSessionKey CryptImportKey CryptProtectData CryptQueryObject CryptReleaseContext CryptSetHashParam CryptSetKeyParam CryptSetProvider CryptSetProviderEx CryptSetProvParam CryptSignHash CryptUnprotectData CryptVerifySignature Az alapértelmezett CSP meghatározása. Hash objektum működési paramétereinek lekérdezése. Kulcs működési paramétereinek lekérdezése. CSP működési paramétereinek lekérdezése. Kezelőt rendel egy nem időleges felhasználói kulcspárhoz. Hash függvény végrehajtása egy sztringen. Hash függvény végrehajtása egy kulcson. Kulcsok másolása egy key blob-ból egy CSP-be. DATA BLOB-beli adatok titkosítása. A megadott CERT BLOB-ról vagy fájlról információ kérése. CSP és key container kezelők felszabadítása. Hash objektum működésének beállítása. Kulcs műveletek működésének beállítása. Az alapértelmezett felhasználói CSP megadása. Az aktuális felhasználó vagy az adott számítógép alapértelmezett
CSP-jének megadása. CSP műveletek működésének beállítása. Hash objektum digitális „aláírása”. DATA BLOB-beli adatok visszaállítása és integritásának ellenőrzése. Hash objektum „aláírásának” ellenőrzése. Most szeretnék kitérni azokra a függvényekre, amelyeket a programok megvalósítása során felhasználtam. 5.421 CryptAcquireContext A CryptAcquireContext függvény által juthatunk hozzá egy kezelőhöz egy adott CSP-n belüli key container-hez. Ezután ezt a kezelőt használva végezhetünk műveleteket az adott CSP-n. Először is megpróbál találni egy olyan CSP-t, amely megfelel a dwProvType és pszProvider paraméterek által megadott leírásnak. Ha talál ilyet, akkor megpróbál találni egy, a pszContainer paraméterben megadott nevű key container-t a CSP-ben A funkció szintén alkalmas key container-ek létrehozására és törlésére Formátum: #include <wincrypt.h> BOOL WINAPI CryptAcquireContext( HCRYPTPROV *phProv,
// out LPCTSTR pszContainer, // in LPCTSTR pszProvider, // in DWORD dwProvType, // in DWORD dwFlags // in ); 105 Az alábbi előredefiniált kódolási algoritmusokat támogatja: - PROV RSA FULL - PROV RSA SIG - PROV DSS - PROV DSS DH - PROV DH SCHANNEL - PROV FORTEZZA - PROV MS EXCHANGE - PROV RSA SCHANNEL - PROV SSL Ha a függvény FALSE értékkel tér vissza, akkor a GetLastError windows funkcióval meghatározhatjuk a hiba okát. 5.422 CryptCreateHash A CryptCreateHash függvény egy sztringen történő hash függvény végrehajtásának az első lépése. Visszatérési értéke egy kezelő egy CSP hash objektumra Azután ennek segítségével végezhetünk hash műveleteket Formátum: #include <wincrypt.h> BOOL WINAPI CryptCreateHash( HCRYPTPROV hProv, // in ALG ID Algid, // in HCRYPTKEY hKey, // in DWORD dwFlags, // in HCRYPTHASH *phHash // out ); Az alábbi hash algoritmusok vannak támogatva: Paraméterérték CALG HMAC CALG MAC CALG MD2 CALG
MD5 CALG SHA CALG SHA1 CALG SSL3 SHAMD5 Leírás HMAC, egy kulcsot használó hash algoritmus Message Authentication Code MD2 MD5 US DSA Secure Hash Algorithm mint az előző SSL3 kliens autentikáció Ha a függvény FALSE értékkel tér vissza, akkor a GetLastError Windows funkcióval meghatározhatjuk a hiba okát. 106 5.423 CryptDecrypt A CryptDecrypt függvény segítségével lehet egy előzőleg CryptEncrypt-tel kódolt adatblokkot visszaállítani. Formátum: #include <wincrypt.h> BOOL WINAPI CryptDecrypt( HCRYPTKEY hKey, // in HCRYPTHASH hHash, // in BOOL Final, // in DWORD dwFlags, // in BYTE *pbData, // in/out DWORD *pcbData // in/out ); Ha nagyméretű adatblokkot kívánunk dekódolni, akkor ezt kötegekre bontva is megtehetjük. Egyszerűen minden kötegre hívjuk meg egymás után a CryptDecrypt függvényt Az utolsó kötegnél a Final paraméter értéke legyen TRUE, és a dekódoló eljárás megfelelően lezárja a dekódolási folyamatot. Ha a
függvény FALSE értékkel tér vissza, akkor a GetLastError Windows funkcióval meghatározhatjuk a hiba okát. 5.424 CryptDestroyHash A CryptDestroyHash függvény megsemmisíti a hHash paraméter által jelzett hash objektumot. Mivel memóriát foglal, mindenképpen javasolt használat után a hash objektumokat megsemmisíteni Formátum: #include <wincrypt.h> BOOL WINAPI CryptDestroyHash( HCRYPTHASH hHash // in ); Ha a függvény FALSE értékkel tér vissza, akkor a GetLastError Windows funkcióval meghatározhatjuk a hiba okát. 5.425 CryptEncrypt A CryptEncrypt funkció segítségével lehet adatokat kódolni. Az algoritmus az adatokat a hKey paraméter által jelzett, CSP-beli kulccsal kódolja. Formátum: #include <wincrypt.h> BOOL WINAPI CryptEncrypt( HCRYPTKEY hKey, // in HCRYPTHASH hHash, // in BOOL Final, // in DWORD dwFlags, // in BYTE *pbData, // in/out 107 DWORD *pcbData, DWORD cbBuffer ); // in/out // in Ha nagyméretű adatblokkot kívánunk
kódolni, akkor ezt kötegekre bontva is megtehetjük. Egyszerűen minden kötegre hívjuk meg egymás után a CryptEncrypt függvényt Az utolsó kötegnél a Final paraméter értéke legyen TRUE, és a kódoló eljárás megfelelően lezárja a kódolási folyamatot. Ha a függvény FALSE értékkel tér vissza, akkor a GetLastError Windows funkcióval meghatározhatjuk a hiba okát. 5.426 CryptDeriveKey A CryptDeriveKey függvény kulcsot állít elő a megadott adatokból. Ez a funkció biztosítja, hogy a kulcsgenerálás determinisztikus, azaz ugyanabból a bemenő adatból minden számítógépen ugyanaz a kulcs lesz, ha ugyanazt a CSP-t és algoritmusokat használjuk A megadott adat lehet például egy jelszó, vagy bármilyen más adat is Formátum: #include <wincrypt.h> BOOL WINAPI CryptDeriveKey( HCRYPTPROV hProv, // ALG ID Algid, // HCRYPTHASH hBaseData, // DWORD dwFlags, // HCRYPTKEY *phKey // ); in in in in in/out A Microsoft Base Cryptographic Provider
szimmetrikus kulcsok előállítására két algoritmust használ: - RC2 block cipher - RC4 stream cipher Ha a függvény FALSE értékkel tér vissza, akkor a GetLastError Windows funkcióval meghatározhatjuk a hiba okát. 5.427 CryptHashData A CryptHashData függvény segítségével lehet hash függvényeket futtatni sztringeken. Formátum: #include <wincrypt.h> BOOL WINAPI CryptHashData( HCRYPTHASH hHash, // in BYTE *pbData, // in DWORD cbData, // in DWORD dwFlags // in ); 108 Ha a függvény FALSE értékkel tér vissza, akkor a GetLastError Windows funkcióval meghatározhatjuk a hiba okát. 5.428 CryptDestroyKey A CryptDestroyKey függvény megsemmisíti a megadott kulcshoz tartozó kezelőt. Mindenképpen tanácsos meghívni ezt a függvényt, ugyanis bizonyos CSP-k, például egy intelligens kártyán implementált CSP, nagyon csekély memóriával rendelkezik a kulcsok tárolására. Formátum: #include <wincrypt.h> BOOL WINAPI CryptDestroyKey(
HCRYPTKEY hKey // in ); Ha a függvény FALSE értékkel tér vissza, akkor a GetLastError Windows funkcióval meghatározhatjuk a hiba okát. 5.429 CryptReleaseContext A CryptReleaseContext függvény használatával felszabadíthatjuk a CSP-hez és a key container-hez tartozó kezelőt. Ezt szükséges meghívni, ha már nem kívánjuk tovább használni a CSP-t. Formátum: #include <wincrypt.h> BOOL WINAPI CryptReleaseContext( HCRYPTPROV hProv, // in DWORD dwFlags // in ); Ha a függvény FALSE értékkel tér vissza, akkor a GetLastError Windows funkcióval meghatározhatjuk a hiba okát. Példaprogram a CSP használatára #include <wincrypt.h> HCRYPTPROV hProv = 0; BYTE pbData[1000]; DWORD cbData; // Get a handle to the default PROV RSA FULL provider. if(!CryptAcquireContext(&hProv, NULL, NULL, PROV RSA FULL, 0)) { printf("Error %x during CryptAcquireContext! ", GetLastError()); return; } // Read the name of the default CSP. cbData = 1000;
if(!CryptGetProvParam(hProv, PP NAME, pbData, &cbData, 0)) { printf("Error %x reading CSP name! ", GetLastError()); return; } printf("Provider name: %s ", pbData); // Read the name of the default key container. cbData = 1000; if(!CryptGetProvParam(hProv, PP CONTAINER, pbData, &cbData, 0)) { 109 printf("Error %x reading key container name! ", GetLastError()); return; } printf("Key Container name: %s ", pbData); // Perform cryptographic operations. . // Release the provider handle. if(!CryptReleaseContext(hProv, 0)) { printf("Error %x during CryptReleaseContext! ", GetLastError()); return; } // * // Get a handle to the Microsoft Base Cryptographic Provider and the // "KC1" key container. if(!CryptAcquireContext(&hProv, TEXT("KC1"), MS DEF PROV, PROV RSA FULL, 0)) { printf("Error %x during CryptAcquireContext! ", GetLastError()); return; } // Perform cryptographic operations. . // Release the
provider handle. if(!CryptReleaseContext(hProv, 0)) { printf("Error %x during CryptReleaseContext! ", GetLastError()); return; } // * // Get a handle to the default provider. Create a new key container // named "KC2". Note that this key container will be empty until keys // are explicitly created with the CryptGenKey function. lstrcpy(szProv, ); lstrcpy(szContainer, ); if(!CryptAcquireContext(&hProv, TEXT("KC2"), NULL, PROV RSA FULL, CRYPT NEWKEYSET)) { printf("Error %x during CryptAcquireContext! ", GetLastError()); return; } // Perform cryptographic operations. . // Release the provider handle. if(!CryptReleaseContext(hProv, 0)) { printf("Error %x during CryptReleaseContext! ", GetLastError()); return; } 5.43 CSP adattípusok Ebben a szakaszban összefoglalom a CSP által használt adattípusokat és konstans értékeket. ALG ID Az ALG ID adattípus segítségével adhatunk meg különböző kódolási algoritmusokat. Az
adattípust a Wincrypt.h header fájl deklarálja: typedef unsigned int ALG ID; Az algoritmusok azonosítói a következők: Konstans Leírás CALG DSS SIGN Digitális aláírás CALG HMAC* HMAC, kulcsot használó hash algoritmus CALG MD2* MD2 hash algoritmus 110 CALG MD4 CALG MD5* CALG SHA* CALG SHA1* CALG MAC* CALG SSL3 SHAMD5 CALG RSA SIGN* CALG DSS SIGN CALG RSA KEYX* CALG DES CALG RC2* CALG RC4* CALG SEAL MD4 hash algoritmus MD5 hash algoritmus SHA hash algoritmus ua. mint a CALG SHA MAC, kulcsot használó hash algoritmus SSL3 kliens autentikáció RSA signature algoritmus DSA signature algoritmus RSA key exchange algoritmus DES kódoló algoritmus RC2 block kódoló algoritmus RC4 stream kódoló algoritmus SEAL kódoló algorithm Diffie-Hellman store and forward key exchange algoCALG DH SF ritmus CALG DH EPHEM Diffie-Hellman ephemeral key exchange algoritmus Ideiglenes algoritmusazonosító a Diffie-Hellman kulCALG AGREEDKEY ANY csok számára CALG KEA KEYX KEA key
exchange algoritmus (FORTEZZA) CALG SKIPJACK Skipjack block kódoló algoritmus (FORTEZZA) CALG TEK TEK (FORTEZZA) * Az algoritmust a Microsoft Base Cryptographic Provider is támogatja. HCRYPTHASH A HCRYPTHASH adattípust használjuk hash objektumok kezelőjeként. Ezek a kezelők hivatkoznak a megfelelő CSP modulra, amelyet éppen használni szeretnénk. A CSP modul nem engedélyezi, hogy közvetlenül a hash értékeket megváltoztassuk, hanem a kezelőn végezhetünk csak műveleteket. A HCRYPTHASH adattípust a Wincrypt.h header fájl definiálja: typedef unsigned long HCRYPTHASH; HCRYPTKEY A HCRYPTKEY adattípust használjuk kriptográfiai kulcsok kezelőjeként. Ezek a kezelők hivatkoznak a megfelelő CSP modulra, amelyet éppen használni szeretnénk A CSP modul nem engedélyezi, hogy közvetlenül a kulcs értékeket megváltoztassuk, hanem a kezelőn végezhetünk csak műveleteket. A HCRYPTKEY adattípust a Wincrypt.h header fájl definiálja: typedef unsigned long
HCRYPTKEY; HCRYPTPROV A HCRYPTPROV adattípust használjuk CSP-k kezelőjeként. Ezek a kezelők hivatkoznak a megfelelő CSP modulra, amelyet éppen használni szeretnénk A HCRYPTPROV adattípust a Wincrypt.h header fájl definiálja: typedef unsigned long HCRYPTPROV; 111 III. A program forrásnyelvi listája 6. Intelligenskártya-támogatással kiegészített GSView 36 verzió Visual C++ 6 nyelvű forráskódja Az Internetről letölthető GSView 3.6 verzió forráskódja egyetlen ZIP formátumú tömörített állományból áll (gsv36srczip), mely Microsoft Visual C++ vagy Borland C++ segítségével fordítható le Ez kicsomagolva 8 darab fájlt tartalmaz: - az src.zip tartalmazza a tényleges forrásnyelvi kódot - a pstotext.zip és epstoolzip a főprogramhoz tartozó két segédeszköz szintén forrásnyelvi kódja - licence, mely a szoftverrel kapcsolatos licencszerződés (lásd a Mellékletben, mellékelve a magyar nyelvű fordítást is) - readme.htm és
gsviewcss a telepítéssel, fordítással és az általános tudnivalókkal kapcsolatos információk (a weboldal stíluselemeivel) - cdorder.txt egy kinyomtatható űrlapot tartalmaz, melynek segítségével hivatalosan is megrendelhető a szoftver - file id.diz rövid névjegy a szoftverről A kicsomagolt állományok a GSViewGSV36-Source alkönyvtárban találhatók a mellékelt adathordozón. Az ebből az alkönyvtárból nyíló sajat alkönyvtárban találhatóak az általam létrehozott új és a módosított korábbi fájlok. 6.1 Általam létrehozott új fájlok (13 darab) - readme.txt tartalmazza az újonnan létrehozott és a módosított fájlok neveit a licencszerződésben foglaltaknak megfelelően - secure.cpp tartalmazza a teljes autentikációs mechanizmust - secure.h a hozzá tartozó fejrész (deklaráció) - scindlg.cpp a SIM kártya védett adatainak való hozzáféréséhez és a kártyabirtokos azonosságának ellenőrzéséhez szükséges PIN kód
bekérését végző dialógusablak implementációja - scindlg.h a hozzá tartozó fejrész (deklaráció) - resource.h a dialógusablakhoz definiált konstansok - secure1.rc a dialógusablak megjelenését meghatározó erőforrásfájl - scard.cpp az intelligenskártya-támogatás implementációja - scard.h a hozzá tartozó fejrész (deklarációk) és típusdefiníciós fájl - s crypt.cpp a minden számítógépen implementációtól függetlenül végezhető dekódolás támogatása - s crypt.h a hozzá tartozó fejrész (deklaráció) 112 - extr.bin az engedélyezett hozzáférésű SIM kártyák adatait tartalmazó kódolt példafájl - build.bat a fordításhoz szükséges környezeti változók beállítása 6.2 A módosított korábbi fájlok (10 darab) - gvwin.cpp a főprogram - gvcrc.h konstansdefiníciós fájl - gvwin2.rc az angol nyelvű erőforrások definíciós fájl - degvclang.rc, engvclangrc, esgvclangrc, frgvclangrc, itgvclangrc
a nyelvi erőforrások definíciós fájljai - gvwinvc.mak a Microsoft Visual C++ segítségével lefordítandó makefile - gvwinc.mak az összetevők fordítását végző fordítófüggetlen makefile 6.3 A forrásnyelvi listák elemzése A nyomtatott verzióban csak a kódhoz tartozó magyarázatok találhatók, az alábbi forrásnyelvi listák terjedelmi okokból a CD-mellékletre kerültek. A GSViewGSV36Source alkönyvtárból nyíló sajat alkönyvtárban találhatók meg A részletes forráslistákat csak akkor közlöm teljes egészében, ha azt újonnan én hoztam létre, különben csak az eszközölt módosításokat mutatom be, kiemelve a módosítás szűkebb környezetét, magát a módosítást félkövéren szedve. 6.31 Gvwincpp A főprogram (gvwin.cpp) elejére elhelyeztem egy függvényhívást, közvetlenül a WinMain függvény első utasításaként annak eldöntésére, hogy a felhasználó rendelkezik-e a megfelelő jogosítványokkal a program
futtatására. Ez a secureh-ban deklarált Identifying függvény. Természetesen szükség volt még a megfelelő #include ”secure.h” makró beiktatására is /* Copyright (C) 1993-2000, Ghostgum Software Pty Ltd. All rights reserved. This file is part of GSview. This program is distributed with NO WARRANTY OF ANY KIND. No author or distributor accepts any responsibility for the consequences of using it, or for whether it serves any particular purpose or works at all, unless he or she says so in writing. Refer to the GSview Free Public Licence (the "Licence") for full details. Every copy of GSview must include a copy of the Licence, normally in a plain ASCII text file named LICENCE. The Licence grants you the right to copy, modify and redistribute GSview, but only under certain conditions described in the Licence. Among other things, the Licence requires that the copyright notice and this notice be preserved on all copies. */ /* gvwin.c */ /* Main routines for Windows
GSview / #include "gvwin.h" //* #include "secure.h" //* 113 char szAppName[MAXSTR] = GSVIEW PRODUCT; char szExePath[MAXSTR]; char szIniFile[MAXSTR]; /* application name - for title bar / [.] int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow) { //* //checks the smartcard int sec ret=Identifying(); if (sec ret<0) exit(sec ret); //* MSG msg; LPSTR command line; [.] 6.32 Secureh A header fájl egyetlen függvényt deklarál, melynek szerepe az, hogy ha visszatérési értékként negatív egész szám szerepel, akkor a program a negatív értékkel terminál. Külön figyelmeztető üzenetre azért nincs szükség, mert mint látni fogjuk nem megfelelő kártya esetén is lehetőség van az „újrapróbálkozásra”, a kilépés kizárólag a felhasználó kérésére történik, vagy valamely súlyos probléma esetén. /* Copyright (C) 1993-2000, Ghostgum Software Pty Ltd. All rights reserved. This file is
part of GSview. This program is distributed with NO WARRANTY OF ANY KIND. No author or distributor accepts any responsibility for the consequences of using it, or for whether it serves any particular purpose or works at all, unless he or she says so in writing. Refer to the GSview Free Public Licence (the "Licence") for full details. Every copy of GSview must include a copy of the Licence, normally in a plain ASCII text file named LICENCE. The Licence grants you the right to copy, modify and redistribute GSview, but only under certain conditions described in the Licence. Among other things, the Licence requires that the copyright notice and this notice be preserved on all copies. */ /* secure.h */ /* Security function prototypes for GSview / // SC main int Identifying(void); 6.33 Securecpp A fájl a szükséges include-ok után egy külső globális változót deklarálunk, mert a HINSTANCE hlanguage nevű változó segítségével férhetünk hozzá az
erőforrásdefiníciós fájlokhoz, és később a LoadString(hlanguage, IDCA ERRCA, buf, sizeof(buf)) függvény segítségével kapjuk meg a kiírandó hibaüzenet (IDCA ERRCA) szövegét. Szintén globális változóként létrehozzuk a CScard osztály egy példányát, mert erre több függvényben is szükség van, csakúgy, mint a serial és imsi nevű karaktertömbökre, ezek tartalmazzák ugyanis a nevük által jelzett információt. Ezután következik a GetSIMSerial(void) függvény megadása, melynek feladata az aktuális SIM kártya két adatának, a sorszámnak és az IMSI számnak a 114 data az aktuális SIM kártya két adatának, a sorszámnak és az IMSI számnak a meghatározása. Az ellenőrzés úgy történik, hogy az Identifying(void) függvény inicializálja a kártyaolvasót, a hibaüzenetek nyelvét angolra állítja (az alapbeállítás a német), majd betölti az erőforrások közül a hibaüzenet-sztringet. Ezután a GetSIMSerial értéket ad a
globális változóknak Létrehozzuk a Decrypt osztály egy példányát, amely dekódolja az érvényes kártyaadatokat tartalmazó fájlt úgy, hogy minden hívásra a következő érvényes kártyaadatot adja vissza. Nem marad más hátra, mint az aktuális kártyaadatokat (serial, imsi) összehasonlítani a kapott értékekkel. Ha van egyező érték, akkor a visszatérési érték (retval) 1 lesz, ha nincs, akkor ki kell írni a hibaüzenetet, és lehetőséget adni az újrapróbálkozásra. A GetSIMSerial függvény kezdetben kiválasztja a SIM kártya gyökérkönyvtárát (3f00), majd az itt található sorszámot tartalmazó bináris fájlt (2fe2). Ezután beolvassa az értéket a serial nevű változóba, ügyelve arra, hogy a fájl az adatokat BCD formátumban tartalmazza, és az alacsonyabb helyiértékű szám megelőzi a magasabb helyiértékű számot. Hasonlóan beolvassa az IMSI-t tartalmazó szintén bináris fájlt azzal a különbséggel, hogy ez a főkönyvtáron
belül a GSM alkönyvtárban (7f20) található és az azonosítója 6f07. Mindemellett az IMSI védett adatnak számít, és csak PIN kóddal (vagy ha a PIN kód ki van kapcsolva) olvasható. Ezért ha először nem sikerül beolvasni, az EnterPIN(Temppin) függvény, melyet az scindlg.h fájlban deklarálunk, rákérdez a PIN kódra és azt a Temppin változóba helyezi. PIN ellenőrzés után már beolvasható a kért adat az imsi változóba. Ha bármilyen probléma adódna a függvény visszatér, változatlanul hagyva a kérdéses változót /* Copyright (C) 1993-2000, Ghostgum Software Pty Ltd. All rights reserved. This file is part of GSview. This program is distributed with NO WARRANTY OF ANY KIND. No author or distributor accepts any responsibility for the consequences of using it, or for whether it serves any particular purpose or works at all, unless he or she says so in writing. Refer to the GSview Free Public Licence (the "Licence") for full details. Every
copy of GSview must include a copy of the Licence, normally in a plain ASCII text file named LICENCE. The Licence grants you the right to copy, modify and redistribute GSview, but only under certain conditions described in the Licence. Among other things, the Licence requires that the copyright notice and this notice be preserved on all copies. */ /* secure.cpp */ /* Security functions for GSview / #include "scard.h" #include "gvcrc.h" #include <iostream.h> #include "scindlg.h" #include "s crypt.h" extern HINSTANCE hlanguage; CScard card; char serial[100]={ }; char imsi[100]={ }; void GetSIMSerial(void) { //Serial number //Information from card 115 int i; char buf[255]; char DataOut[12]={0}; char FileID[2]={0x3f,0x00}; //Select MasterFile Error myError; char Statuserr[32]={0}; //Select root if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ return; } if (0x9f!=(unsigned char)DataOut[0]) { //Not available return; } //Select
ICC-ID FileID[0]=0x2f; FileID[1]=0xe2; //Select file containing serial number if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ return; } if (0x9f!=(unsigned char)DataOut[0]) { return; } //format of file: binary if(myError=card.ReadBinary(10, DataOut, sizeof(DataOut))){ return; } if ((0x90!=(unsigned char)DataOut[0])||(0x00!=(unsigned char)DataOut[1])) { return; } //value loaded serial[0]= ; char tag[2]; for(i=0; i<10; i++) { //inverted order! sprintf(tag, "%x",((unsigned char) DataOut[2+i])%16); strcat(serial, tag); sprintf(tag, "%x",((unsigned char) DataOut[2+i])/16); strcat(serial, tag); } //International Mobile Subscribing Identity //Information from card //Select MasterFile FileID[0]=0x3f; FileID[1]=0x00; //Select root if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ return; } if (0x9f!=(unsigned char)DataOut[0]) { //Not available return; } //Select directory GSM FileID[0]=0x7f; FileID[1]=0x20; //Select directory GSM
if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ return; } if (0x9f!=(unsigned char)DataOut[0]) { //Not available return; } //Select IMSI FileID[0]=0x6f; FileID[1]=0x07; //Select file containing IMSI if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ return; 116 } if (0x9f!=(unsigned char)DataOut[0]) { return; } //format of file: binary if(myError=card.ReadBinary(9, DataOut, sizeof(DataOut))){ return; } if ((0x98==(unsigned char)DataOut[0])||(0x04==(unsigned char)DataOut[1])) {//need PIN code char Temppin[8]; EnterPIN(Temppin); if ( ==Temppin[0]) return; //Cancel //check PIN code if(myError=card.VerifyPin(1, Temppin, DataOut, sizeof(DataOut))){ return; } if ((0x90!=(unsigned char)DataOut[0])||(0x00!=(unsigned char)DataOut[1])) { //MessageBox("Invalid PIN code!","checking PIN",MB OK); return; } //format of file: binary if(myError=card.ReadBinary(9, DataOut, sizeof(DataOut))){ return; } } if ((0x90!=(unsigned
char)DataOut[0])||(0x00!=(unsigned char)DataOut[1])) { return; } //loaded imsi[0]= ; //byte 0: length //byte 1: low nibble=parity //upper nibble=1st digit sprintf(tag, "%x",((unsigned char) DataOut[3])/16); strcat(imsi, tag); for(i=2; i<9; i++) { //inverted order! sprintf(tag, "%x",((unsigned char) DataOut[2+i])%16); strcat(imsi, tag); sprintf(tag, "%x",((unsigned char) DataOut[2+i])/16); strcat(imsi, tag); } } //using the smartcard reader int Identifying(void) { int i,k; int retval=0; char buf[255]; for (i=0; i<255; i++) buf[i]=0; Error myError; long tmpszam; //Smartcard init myError=card.Init(); if(myError) { card.GetErrText(buf); MessageBox(NULL,buf,"Error",MB OK); return -1; } //Environmental settings char nyelv[20]="ENGLISH "; if(myError=card.SetLng(nyelv)){ MessageBox(NULL,"The English language resources arent available.", "Error", MB OK); } 117 LoadString(hlanguage, IDCA ERRCA, buf, sizeof(buf));
//Parameters of smartcard GetSIMSerial(); char egysor[255]; FILE *fhandler; int eof; char temp[30]; while (!retval) { //check parameters //Decode Decrypt dcr; eof=dcr.DecodeData(egysor); while ((!eof)&&(!retval)) { //serial number for (i=0; i<20; i++) temp[i]=egysor[i]; temp[i]= ; if (0==strcmp(serial, temp)) { //IMSI number for (i=0; i<15; i++) temp[i]=egysor[i+20]; temp[i]= ; if (0==strcmp(imsi, temp)) retval=1; } eof=dcr.DecodeData(egysor); } //close file and release memory dcr.~Decrypt(); if (!retval) {//error if (IDCANCEL==MessageBox(NULL, buf, "Error", MB RETRYCANCEL)) {//exit retval=-1; } else {//retry GetSIMSerial(); } } } card.~CScard(); return retval; } 6.34 Gvcrch A főprogramhoz tartozó konstansdefiníciós-fájlban adunk értéket az IDCA ERRCA konstansnak, amely egyébként az erőforrásdefiníciós-fájlokban tárolt hibaüzenet azonosítója. [.] #define CDSC RESOURCE INCORRECT USAGE #define CDSC RESOURCE INCORRECT USAGE2 //Smartcard strings
#define IDCA ERRCA 2430 2431 1900 6.35 Degvclangrc, Engvclangrc, Esgvclangrc, Frgvclangrc, Itgvclangrc A nyelvi sztringeket definiálják ezek a fájlok, a hibaüzenet hozzátéve módosítottam rajtuk. Sajnos mindegyikhez ugyanazt az angol nyelvű szöveget fűztem Csak az angol nyelvű módosítása azért nem lett volna célszerű, mert más nyelvet beállítva fordítási hibát jelentene, így mindet módosítottam. 118 [] GSVS(CDSC RESOURCE INCORRECT USAGE2, "") END STRINGTABLE BEGIN GSVS(IDCA ERRCA, "Invalid or unreadable smartcard") END 6.36 Scardh Ez a header fájl definiálja a CScard osztályt, ezáltal az intelligens kártyához való hozzáférés műveleteit. Megadjuk az allerror felsorolási típust, majd a konstruktor, a destruktor és a Comand nevű művelet inline módon, s a többi művelet is deklarálásra kerül. A Comand közvetlenül a Scarddll egyik műveletét használva teremt kapcsolatot az ScardServerrel, így minden
implementált művelet nem más, mint a Comand valamilyen felparaméterezése. Bizonyos lassú kártyaolvasóknál, vagy alacsonyabb teljesítményű számítógépeken a kikommentezett részek beszúrása szükséges lehet (minden műveletre 750 ezredmásodpercet vár), azonban ha az olvasó nem jelez hibát, szükségtelen az üresjárat. (Nem is számolva azzal, hogy például egy telefonkönyv kb 200 bejegyzésének beolvasása a szükséges néhány másodperc helyett percekig tarthat) Az implementált műveleteknél jeleztem, hogy melyik szabvány definiálja A GSM műveleteket az ETSI által definiált SIM műveleteknek megfelelően adtam meg, egyetlen kivétel a SetPinStatus(int onoff, char pincode[8], LPSTR lpBuffer, int bufSize), ahol az onoff változótól függően két különböző művelet (ENABLE-PIN, DISABLE-PIN) hajtódik végre. A nem GSM SetLng(LPSTR lpNyelv) és a GetErrText(char *errtext) műveleteket pedig az SCARD dokumentációnak megfelelően alakítottam ki.
/* Copyright (C) 1993-2000, Ghostgum Software Pty Ltd. All rights reserved. This file is part of GSview. This program is distributed with NO WARRANTY OF ANY KIND. No author or distributor accepts any responsibility for the consequences of using it, or for whether it serves any particular purpose or works at all, unless he or she says so in writing. Refer to the GSview Free Public Licence (the "Licence") for full details. Every copy of GSview must include a copy of the Licence, normally in a plain ASCII text file named LICENCE. The Licence grants you the right to copy, modify and redistribute GSview, but only under certain conditions described in the Licence. Among other things, the Licence requires that the copyright notice and this notice be preserved on all copies. */ /* scard.h */ //SCARD Server function prototypes #include <afxwin.h> // MFC core and standard components #ifndef SCARD H #define SCARD H enum allerror{ noErr = 0, termWinErr, dllErr, initFailed,
portNotAvail portUsedByOther = 1001, = 1002, 119 noTermOnPort termLockedBy appSoftNotComp unknownCommand failExecCommand failExecTerm invalidParamCommand cardAccessFail PinErr serverNotAvail noCard cardRemove invalidCard cardEjectFail endofErr = 32000 = = = = 1008, 1009, 1010, 1200, = 1201, = 1202, = 1203, = 1310, = 1311, = 2000, = 4000, = 4001, = 4002, = 4003, }; typedef allerror Error; typedef LONG (FAR PASCAL *SCARDPROC) (LPINT, LPSTR, LPINT, LPSTR, LPINT, VOID, LPINT); class CScard{ public: bool debug; CScard():m hScardDll(NULL), m hand(0), m ScardCommand(NULL) { m lpHand = &m hand; } ~CScard(){Quit();} void Quit() { if(m hScardDll) FreeLibrary(m hScardDll); m hScardDll = NULL; } //Initialize Smartcard reader Error Init(); //function GET RESPONSE (ETSI GSM 11.11, 43110) Error GetMessage(int Le, LPSTR lpBuffer, int bufSize); //function SELECT (ETSI GSM 11.11, 4311) Error SelectFile(char fileID[2], LPSTR lpBuffer, int bufSize); //function VERIFY-PIN (ETSI GSM 11.11,
4313) Error VerifyPin(int pinnum, char pincode[8], LPSTR lpBuffer, int bufSize); //function DISABLE-PIN (ETSI GSM 11.11, 4315) and function ENABLE-PIN (ETSI GSM 11.11, 4316) Error SetPinStatus(int onoff, char pincode[8], LPSTR lpBuffer, int bufSize); //function READ BINARY (ETSI GSM 11.11, 4318) Error ReadBinary(int Le, LPSTR lpBuffer, int bufSize); //function UPDATE BINARY (ETSI GSM 11.11, 43111) Error WriteBinary(int Le, LPSTR InBuffer, LPSTR lpBuffer, int bufSize); //function READ RECORD (ETSI GSM 11.11, 4319) Error ReadRecord(int P1, int P2, int nbytes, LPSTR lpBuffer, int bufSize); //function UPDATE RECORD (ETSI GSM 11.11, 43112) Error WriteRecord(int P1, int P2, int nbytes, LPSTR InBuffer, LPSTR lpBuffer, int bufSize); //function System,SetLng (SCARD SERVER V2.14) Error SetLng(LPSTR lpNyelv); //function System,Info,ErrText (SCARD SERVER V2.14) void GetErrText(char *errtext); //Run command string Error Comand(LPSTR cmd, LPINT cmdLen, LPSTR lpDataIn, LPINT lpDataInLen, LPSTR
lpDataOut, LPINT lpDataOutLen) { //You need to use either this block or the same block in Scard.cpp to wait for correct answer //In case of error try to use both command blocks, although they do the same //----BEGIN---/* MSG msg; const long DelayTime = 750; //miliseconds long lBegin = GetTickCount(); long lNow; 120 do{ PeekMessage(&msg, NULL, 0, 0, PM REMOVE); TranslateMessage(&msg); DispatchMessage(&msg); lNow = GetTickCount(); }while (lNow - lBegin < DelayTime); */ //----END---Error err; err=(Error)m ScardCommand(m lpHand, cmd, cmdLen, lpDataIn, lpDataInLen, lpDataOut, lpDataOutLen); return err; } private: HINSTANCE m hScardDll; SCARDPROC m ScardCommand; INT m hand; LPINT m lpHand; }; #endif // SCARD H 6.37 Scardcpp Ez a fájl tartalmazza a szükséges műveletek implementációját. Igazából az egyetlen említésre méltó függvény a CScard::Init(), mely betölti az Scard32.dll-t és létrehozza az m ScardCommand nevű változót, mely az Scard32dllbeli
SCardComand függvényhívásra mutat Ennek a függvénynek szüksége van a 750 ezredmásodperces várakozásra, különben hibával tér vissza, ezért ha a header fájlban nem engedélyeztük, itt szükséges beiktatni a várakozást. Minden más művelet, mint ahogy korábban említettem csak a Comand függvény megfelelő paraméterekkel történő meghívása. A parancsformátum a következő: 1. parancssztring, 2 parancssztringhossz, 3 inputsztring, 4. inputsztringhossz, 5 outputsztring, 6 outputsztringhossz /* Copyright (C) 1993-2000, Ghostgum Software Pty Ltd. All rights reserved. This file is part of GSview. This program is distributed with NO WARRANTY OF ANY KIND. No author or distributor accepts any responsibility for the consequences of using it, or for whether it serves any particular purpose or works at all, unless he or she says so in writing. Refer to the GSview Free Public Licence (the "Licence") for full details. Every copy of GSview must include a copy
of the Licence, normally in a plain ASCII text file named LICENCE. The Licence grants you the right to copy, modify and redistribute GSview, but only under certain conditions described in the Licence. Among other things, the Licence requires that the copyright notice and this notice be preserved on all copies. */ /* scard.cpp */ //SCARD Server functions #include "Scard.h" Error CScard::Init() { INT i; Error err = initFailed; debug = 0; m hScardDll = LoadLibrary("SCARD32.DLL"); 121 if(m hScardDll){ m ScardCommand = (SCARDPROC)GetProcAddress(m hScardDll, "SCardComand"); err = noErr; if(m ScardCommand){ // Test err = (Error)m ScardCommand(&m hand, NULL, &i, NULL, &i, NULL, &i); //In case of error try to use this command block, too. //----BEGIN---/* if(err == noErr){ LPSTR lpCmd = "Device,Select,-1"; INT len = strlen(lpCmd); err = Comand(lpCmd, &len, NULL, &i, NULL, &i); } */ //----END---//You need to use either this
block or the same block in Scard.h to wait for correct answer //----BEGIN---MSG msg; const long DelayTime = 750; //miliseconds long lBegin = GetTickCount(); long lNow; do{ PeekMessage(&msg, NULL, 0, 0, PM REMOVE); TranslateMessage(&msg); DispatchMessage(&msg); lNow = GetTickCount(); }while (lNow - lBegin < DelayTime); //----END---LPSTR lpCmd = "Card,Info,Status"; INT len = strlen(lpCmd); char DataOut[32]; int sizeout=32; //wait for initializing err=(Error)Comand(lpCmd, &len, NULL, &i, DataOut, &sizeout); } } return err; } //function System,SetLng (SCARD SERVER V2.14) Error CScard::SetLng(LPSTR lpNyelv) { char cmd[32]; //default: GERMAN sprintf(cmd, "System,SetLng,%s",lpNyelv); int cmdlen=strlen(cmd); int sizeOut=2; char DataOut[32]="