Informatika | Tanulmányok, esszék » Lusztig Péter - Intelligens kártyára alapozott autentikáció

Alapadatok

Év, oldalszám:2004, 237 oldal

Nyelv:magyar

Letöltések száma:66

Feltöltve:2008. szeptember 27.

Méret:802 KB

Intézmény:
-

Megjegyzés:

Csatolmány:-

Letöltés PDF-ben:Kérlek jelentkezz be!



Értékelések

Nincs még értékelés. Legyél Te az első!


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]=""; int sizeIn=0; char DataIn[32]=""; Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, DataOut, &sizeOut); return err; } //function System,Info,ErrText (SCARD SERVER V2.14) void

CScard::GetErrText(char *errtext) {//Get text of last error (max 255 characters) char cmd[32]; sprintf(cmd, "System,Info,ErrText"); int cmdlen=strlen(cmd); int sizeOut=255; int sizeIn=0; char DataIn[32]; Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, errtext, &sizeOut); } 122 //function VERIFY-PIN (ETSI GSM 11.11, 4313) Error CScard::VerifyPin(int pinnum, char pincode[8], LPSTR lpBuffer, int bufSize) { int i; char cmd[32]; sprintf(cmd, "Card,APDU"); int cmdlen=strlen(cmd); int sizeOut=2; char DataIn[32]={0xa0,0x20,0x00,0x00,0x08}; DataIn[3]=(char)(pinnum); for(i=0; i<8; i++) DataIn[5+i]=(char)(pincode[i]); int sizeIn=13; Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, lpBuffer, &sizeOut); return err; } //function DISABLE-PIN (ETSI GSM 11.11, 4315) and //function ENABLE-PIN (ETSI GSM 11.11, 4316) Error CScard::SetPinStatus(int onoff, char pincode[8], LPSTR lpBuffer, int bufSize) { int i; char cmd[32]; sprintf(cmd,

"Card,APDU"); int cmdlen=strlen(cmd); int sizeOut=2; char DataIn[32]={0xa0,0x26,0x00,0x01,0x08}; //disable PIN if (onoff) DataIn[1]=0x28; for(i=0; i<8; i++) DataIn[5+i]=(char)(pincode[i]); int sizeIn=13; //enable PIN Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, lpBuffer, &sizeOut); return err; } //function SELECT (ETSI GSM 11.11, 4311) Error CScard::SelectFile(char fileID[2], LPSTR lpBuffer, int bufSize) { int i; char cmd[32]; sprintf(cmd, "Card,APDU"); int cmdlen=strlen(cmd); int sizeOut=2; char DataIn[32]={0xa0,0xa4,0x00,0x00,0x02}; for(i=0; i<2; i++) DataIn[5+i]=(char)(fileID[i]); int sizeIn=7; Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, lpBuffer, &sizeOut); return err; } //function READ BINARY (ETSI GSM 11.11, 4318) Error CScard::ReadBinary(int Le, LPSTR lpBuffer, int bufSize) { char cmd[32]; sprintf(cmd, "Card,APDU"); int cmdlen=strlen(cmd); int sizeOut=bufSize; char DataIn[32]={0xa0,0xb0,0x00,0x00};

DataIn[4]=(char)Le; int sizeIn=5; Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, lpBuffer, &sizeOut); 123 return err; } //function UPDATE BINARY (ETSI GSM 11.11, 43111) Error CScard::WriteBinary(int Le, LPSTR InBuffer, LPSTR lpBuffer, int bufSize) { char cmd[32]; sprintf(cmd, "Card,APDU"); int cmdlen=strlen(cmd); int sizeOut=bufSize; char DataIn[255]={0xa0,0xd6,0x00,0x00}; DataIn[4]=(char)Le; for (int i=0; i<Le; i++) { DataIn[5+i]=InBuffer[i]; } int sizeIn=5+Le; Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, lpBuffer, &sizeOut); return err; } //function READ RECORD (ETSI GSM 11.11, 4319) Error CScard::ReadRecord(int P1, int P2, int nbytes, LPSTR lpBuffer, int bufSize) { //P2=4 -> read record P1 char cmd[32]; sprintf(cmd, "Card,APDU"); int cmdlen=strlen(cmd); int sizeOut=bufSize; char DataIn[32]={0xa0,0xb2}; DataIn[2]=(char)P1; DataIn[3]=(char)P2; DataIn[4]=(char)nbytes; int sizeIn=5; Error err=Comand(cmd, &cmdlen, DataIn,

&sizeIn, lpBuffer, &sizeOut); return err; } //function UPDATE RECORD (ETSI GSM 11.11, 43112) Error CScard::WriteRecord(int P1, int P2, int nbytes, LPSTR InBuffer, LPSTR lpBuffer, int bufSize) { //P2=4 -> write record P1 char cmd[32]; sprintf(cmd, "Card,APDU"); int cmdlen=strlen(cmd); int sizeOut=bufSize; char DataIn[255]={0xa0,0xdc}; DataIn[2]=(char)P1; DataIn[3]=(char)P2; DataIn[4]=(char)nbytes; for (int i=0; i<nbytes; i++) { DataIn[5+i]=InBuffer[i]; } int sizeIn=5+nbytes; Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, lpBuffer, &sizeOut); return err; } //function GET RESPONSE (ETSI GSM 11.11, 43110) Error CScard::GetMessage(int Le, LPSTR lpBuffer, int bufSize) { char cmd[32]; sprintf(cmd, "Card,APDU"); 124 int cmdlen=strlen(cmd); int sizeOut=bufSize; char DataIn[32]={0xa0,0xc0,0x00,0x00}; DataIn[4]=(char)Le; int sizeIn=5; Error err=Comand(cmd, &cmdlen, DataIn, &sizeIn, lpBuffer, &sizeOut); return err; } 6.38 Scindlgh Az

alábbi header fájl egyetlen deklarációt tartalmaz, az EnterPIN(char pinnum[8]) függvényét. A függvény a paraméterként megadott változóba teszi a bekért, maximálisan 8 jegyű PIN kódot Bizonyos kártyák ugyanis a megszokottól eltérően nem 4 jegyű, hanem 8 jegyű kódot fogadnak el, egyébként a GSM specifikációja is ennyiben maximálja a PIN hosszá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. */ /* scindlg.h */ //Smartcard dialog function prototypes void EnterPIN(char pinnum[8]); 6.39 Scindlgcpp Az alábbi fájl a fentebb definiált void EnterPIN(char pinnum[8]) függvény implementációja. Megnyit egy egyszerű dialógusablakot a DialogBoxParam(hlanguage, „CodeDlgBox”, NULL, PassProc, (LPARAM)NULL)) függvény meghívásával, ami az MFC egy dialógusablak konstruktora. A paraméterei alapján felhasználja a CodeDlgBox néven definiált dialógus-erőforrást, a PassProc függvény pedig a dialógusablakot vezérlő procedúra lesz A dialógusablak lekezeli a szokásos üzeneteket, az IDOK üzenetre pedig, mely az „OK” gomb azonosítója, néhány ellenőrzést végez a beírt PIN kódon. /* 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 125 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. */ /* scindlg.cpp */ //Smartcard dialog functions #include "gvwin.h" #include "resource.h" //global variable char passchar[8]; BOOL CALLBACK export PassProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { int i; CHAR lpszPassword[9]; WORD cchPassword; switch(message) { case WM

INITDIALOG: centre dialog(hDlg); return TRUE; case WM COMMAND: switch(LOWORD(wParam)) { case IDOK: // Get the number of characters cchPassword=(WORD) SendDlgItemMessage(hDlg,IDC EDITCODE,EM LINELENGTH,(WPARAM) 0,(LPARAM) 0); if (cchPassword > 8) { MessageBox(hDlg,"Too many characters.","Error",MB OK); EndDialog(hDlg, IDCANCEL); return TRUE; } else if (cchPassword == 0) { MessageBox(hDlg,"No characters entered.","Error",MB OK); EndDialog(hDlg, IDCANCEL); return TRUE; } // Get characters // line 0 SendDlgItemMessage(hDlg,IDC EDITCODE,EM GETLINE,(WPARAM) 0,(LPARAM) lpszPassword); // Null-terminate the string lpszPassword[cchPassword] = 0; //Clear for(i=0; i<8; i++) passchar[i]=0xff; //Save the password into a global var. for(i=0; i<cchPassword; i++) { passchar[i]=lpszPassword[i]; } EndDialog(hDlg, IDOK); return TRUE; case IDCANCEL: EndDialog(hDlg, IDCANCEL); return(TRUE); } default: return(FALSE); } } //Main function, create a dialogbox and

return input 126 void EnterPIN(char pinnum[8]) { if (IDCANCEL==DialogBoxParam(hlanguage, "CodeDlgBox", NULL, PassProc, (LPARAM)NULL)) { pinnum[0]=; } else { for (int i=0; i<8; i++) { pinnum[i]=passchar[i]; } } } 6.310 Secure1rc Az erőforrásfájl némileg eltér a szabványos, Visual Studio által generált formától, ugyanis azzal ellentétben ez kézzel készült, kerülve minden felesleges programsort. Egyszerűbb volt ugyanis nem automatikusan generált forrást használni, mert a Visual C++ ClassWizardja a többi erőforrást is indokolatlanul módosította volna, elszeparálni pedig nem szerettem volna ezen erőforrást a többitől, hiszen gyakorlatilag együtt szerves egészet alkotnak. A CodeDlgBox dialógusablak a „Cancel” és az alapértelmezett „OK” gombokat tartalmazza, egy szerkesztőmezőt (EditBox), amely természetesen titkosított, így a beírt kód helyén csak „*” karakterek láthatók, és egy figyelmeztetést arra nézve, hogy a

helytelen PIN kód(ok) megadása használhatatlanná teheti a SIM kártyát. /* Copyright (C) 1993-1998, 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. */ /* secure1.rc */ /* Resources for GSVIEW.EXE, a graphical interface for MS-Windows Ghostscript */ /* Language dependent / #include

<windows.h> #ifndef DS 3DLOOK #define DS 3DLOOK 0x0004L #endif /* for Windows 95 look / #include "resource.h" CodeDlgBox DIALOG DISCARDABLE 0, 0, 120, 75 STYLE DS MODALFRAME | WS POPUP | WS VISIBLE | WS CAPTION | WS SYSMENU | DS 3DLOOK CAPTION "Enter PIN Code" FONT 8, "MS Sans Serif" BEGIN EDITTEXT IDC EDITCODE,7,40,106,14,ES PASSWORD | ES NUMBER DEFPUSHBUTTON "OK",IDOK,63,56,50,14 PUSHBUTTON "Cancel",IDCANCEL,7,56,50,14 LTEXT "Please enter your PIN code. Invalid PIN code can damage your SIM!", IDC STATIC,7,7,106,32 END 127 6.311 Resourceh A fenti erőforrás-definíció által és a dialógusablakot vezérlő függvény által használt néhány konstans definiálását végzi a fájl. Mivel mindkét helyen szükséges az IDC EDITCODE értéke ezért volt szükség külön header fájlra. /* 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. */ /* resource.h */ // Used by secure1.rc #define IDD CODEDIALOG #define IDC EDITCODE #define IDC STATIC 101 1000 -1 6.312 Gvwin2rc A korábbi erőforrás-definícióhoz hozzákapcsoltam az általam létrehozott új dialógusablak erőforrás-definícióját. A fájl egyébként az egyszerűtől a viszonylag összetettig számos

dialógusablak definícióját tartalmazza, de a szükséges dialógusablak egyedi mivolta miatt újat kellett alkotni [] DEFPUSHBUTTON "OK", 1, 170, 4, 50, 14, BS DEFPUSHBUTTON | WS GROUP | WS TABSTOP PUSHBUTTON "Cancel", 2, 170, 21, 50, 14, WS GROUP | WS TABSTOP PUSHBUTTON "&Setup.", 1024, 170, 41, 50, 14, WS GROUP | WS TABSTOP PUSHBUTTON "&Help", 1038, 170, 75, 50, 14, WS GROUP | WS TABSTOP } #include "secure1.rc" 6.313 S crypth A header fájl a Decrypt osztály definícióját tartalmazza. Egyetlen lényeges művelet az int DecodeData(char *ser), mely visszatérési értéke akkor válik igazzá, ha nincs több rendelkezésre álló adat. Mint korábban említettem, az osztály egy implementációtól függetlenül minden számítógépen ugyanúgy működő dekódolást valósít meg, melyre szükség is van a rendelkezésre álló platformok és operációs rendszerek különbözősége miatt. Azon intelligenskártyák

adatait ugyanis, melyek használatával a felhasználó jogosult elindítani a programot, a meghatározott extrbin fájl a programja jellemző szimmetrikus kulccsal kódolja /* 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. 128 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. */ /* s crypt.h */

//Decrypt function prototypes #include <stdio.h> class Decrypt { private: char *rstring; //storage of data long buffsize; //size of buffer FILE *fhandler; //file handler public: Decrypt(); ~Decrypt(); int DecodeData(char *ser); int lpdec; //pointer to next valid data }; 6.314 S cryptcpp Az implementáció a kötelező fejléc után néhány konstans deklarálásával folytatódik. Eme konstansok módosításával szinte a teljes dekódolási mechanizmust megváltoztathatjuk, úgymint a kulcsokat tartalmazó fájl nevét vagy magát a kódolási algoritmust. Ekkor azonban szükséges a kódolási algoritmusra jellemző egy lépésben kódolandó blokk méretét is megadni. Tekintettel a CALG RC4 algoritmusra, mely egy „stream” kódoló algoritmus, ezen érték 1, de bármilyen blokk kód más értéket kíván, pl a CALG RC2 8 bájtos blokkokban kódol. A dekódolás menete a következő: Megnyitjuk, vagy ha még nem létezik, akkor létrehozzuk, a Windows registryben tárolt

„CL1”-ként megadott kódolási paramétereket. Ezen jellemzőket a Windows elrejti a felhasználók elől, nem elérhetőek az alkalmazás számára sem, csak egy Windows interfészen keresztül. Ezután egy adott „jelszó” alapján különböző hasító függvények használatával elkészítjük a dekódoló algoritmus során használt kulcsot, és annak segítségével nyerjük vissza a titkosított adatokat. Tekintve, hogy a „jelszó” a szoftverre jellemző, előre definiált, így a szoftverbe beépítésre kerül, annak és a dekódolási mechanizmusnak birtokában ugyanis könnyedén módosítani lehetne a jogosult kártyaadatokat tartalmazó fájlt, így nem lehetséges, hogy azt maga a felhasználó gépelje be. Ha azonban egyszerűen konstansként lenne definiálva, akkor a futtatható kódból némi leleményességgel kinyerhető lenne (bár a felhasználónak nincs információja arról pontosan hol helyezkedik el), így egy kizáró vagy művelettel elfedtem

a konkrét értéket a futtatható kódban. Ennek főleg értelmes szövegek jelszóként használatánál van jelentősége, ha az A-Z, a-z és 0-9 karaktereken kívül mást nem használunk. Ez igazából nem túl hatásos védelem önmagában, azonban a felhasználó nincs tudatában a tárolt jelszó eltolási címének. A fájl műveleteket és a dekódolást már a konstruktor elvégzi, az int Decrypt::DecodeData(char *ser) csak egy pointer segítségével 35 bájtos blok129 kokat (sorszám 20 számjegy, IMSI 15 jegy) másol a paraméterként megadott karaktertömbbe. Ha nincs több adat, akkor a visszatérési érték igazzá válik /* 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. */ /* s crypt.cpp */ //Decrypt functions //Covering value #define XORVALUE 54321 //The file containing valid serials #define SERIAL FILENAME "extr.bin" #include #include #include #include //16 bit "s crypt.h" <afxwin.h> <wincrypt.h> <fstream.h> // defines for RC4 stream cipher #define ENCRYPT ALGORITHM CALG RC4 #define ENCRYPT BLOCK SIZE 1 void Errormsg() { char temp[255]; sprintf(temp, "Unable to decode %s",SERIAL FILENAME); MessageBox(NULL,temp, "Error",MB OK); exit(-1); }

Decrypt::Decrypt() { //Decoding Key (XOR to cover!) unsigned char szPassw[255]={0xb3,0x42,0xa2,0x58,0xb1,0x46,0xe7,0x03,0x00};// = PASSWORD int szPasswlen=8;// = PASSWORDLEN int i; if (NULL==(fhandler=fopen(SERIAL FILENAME,"rb"))) Errormsg(); if (ferror(fhandler)) Errormsg(); //size of file fseek(fhandler, 0, SEEK END); buffsize=1+ftell(fhandler); //back to the beginning fseek(fhandler, 0, SEEK SET); //allocate memory if((rstring=(char *)malloc(buffsize)) == NULL) { //out of memory Errormsg(); } lpdec=buffsize-1; rstring[lpdec]=; //XOR to uncover for (i=0; i<szPasswlen; i+=2) { szPassw[i]^=XORVALUE/256; 130 //open file if (i+1<szPasswlen) szPassw[i+1]^=XORVALUE%256; } //Hash functions HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; int eof = 0; unsigned char pbBuffer[255]; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount; //string for decoding //Decode file with a unique key producing from user input // Get handle to the default provider if

(!CryptAcquireContext(&hProv, "CL1", MS DEF PROV, PROV RSA FULL, 0)) { unsigned long errt=GetLastError(); if (errt==NTE BAD KEYSET) {//if not exist in registry then create a new one if (!CryptAcquireContext(&hProv, NULL, NULL, PROV RSA FULL, CRYPT NEWKEYSET)) { Errormsg(); } } else Errormsg(); } // Create a hash object if (!CryptCreateHash(hProv, CALG MD5, 0, 0, &hHash)) { Errormsg(); } // Hash in the password data if (!CryptHashData(hHash, szPassw, szPasswlen, 0)) { Errormsg(); } // Derive a session key from the hash object if (!CryptDeriveKey(hProv, ENCRYPT ALGORITHM, hHash, 0, &hKey)) { Errormsg(); } // Destroy the hash object CryptDestroyHash(hHash); hHash = 0; //Read about 100 bytes in a block // Determine number of bytes to encrypt at a time. This must be a multiple // of ENCRYPT BLOCK SIZE dwBlockLen = 100 - 100 % ENCRYPT BLOCK SIZE; dwBufferLen = dwBlockLen; //Begin decoding do { // Read up to dwBlockLen bytes from source file dwCount = fread(pbBuffer,

1, dwBlockLen, fhandler); if(ferror(fhandler)) { Errormsg(); } eof = feof(fhandler); // Decrypt data if(!CryptDecrypt(hKey, 0, eof, 0, pbBuffer, &dwCount)) { Errormsg(); } //data in pbBuffer: from last block to first block for (i=0; (unsigned int)i<dwCount; i++) { rstring[--lpdec]=pbBuffer[dwCount-i-1]; }//lpdec always points to the next value } 131 while(!eof); //Free memory // Destroy session key if(hKey) CryptDestroyKey(hKey); // Destroy hash object if(hHash) CryptDestroyHash(hHash); // Release provider handle if(hProv) CryptReleaseContext(hProv, 0); } Decrypt::~Decrypt() { //free memory free(rstring); //end of file fclose(fhandler); } //decode encrypted data, return TRUE at the end of data int Decrypt::DecodeData(char *ser) { if ((long)lpdec>=(buffsize-1)) return TRUE; int i; for (i=0; i<35; i++) { ser[i]=rstring[lpdec+i]; } lpdec+=i; return FALSE; } 6.315 Extrbin A jogosult kártyaadatokat tartalmazó kódolt, bináris fájl. Itt csak példaként szerepel, 2

általam megadott kártya jellemzőit tartalmazza. Igazából nem lenne szükséges kódolni sem, ha valamely változtatástól védett helyen lenne megtalálható az Interneten, vagy más hálózaton, és a felhasználói szoftverek autentikáció céljából bármikor hozzáférhetnének, csupán személyiségi jogi okokból kellene esetleg kódolni (passzív védelem). Más a helyzet akkor, ha a szoftver nem léphet online módon kapcsolatba az autentikációs szerverrel, hanem más módon (pl. emailben) terjesztett a jogosult kártyaadatokat tartalmazó fájl Ilyenkor a megfelelő regisztrációs procedúra után hozzáveszik a már meglévő kártyaadatokhoz a leendő felhasználóét, és minden más szoftverpéldány futtatható az adott kártya használatával (az esetleges autentikációs fájl frissítése után), vagy kizárólag az ő kártyaadatait tartalmazó fájlt készítenek, és azt számára eljuttatják, ezzel azonban csak az általa birtokolt programterméket

futtathatja (aktív védelem). A létrehozásához szükséges egy kódolóprogram, ami ezeket a fájlokat elkészíti. Én a tesztelés megvalósításához készítettem a Cardlist nevű programot, ez szintén megtalálható a mellékletek között. 6.316 Gvwinvcmak A Microsoft Visual C++ által használandó makefile. Az elején szükséges néhány környezeti változó beállítása, majd, hogy az NMAKE által lefordítható legyen, szükséges átnevezni Makefile-lá. (Vagy használhatjuk a NMAKE /f gvwinvcmak formát) Egyetlen általam módosított dolog az, hogy a linkeléshez felhasznált library-khoz hozzávettem az nafxcw.lib fájlt is, melyre a dekódolás miatt van szükség 132 [] lib.rsp: makefile echo "$(LIBDIR)shell32.lib" > librsp echo "$(LIBDIR)comdlg32.lib" >> librsp echo "$(LIBDIR)gdi32.lib" >> librsp echo "$(LIBDIR)user32.lib" >> librsp echo "$(LIBDIR)winspool.lib" >> librsp echo

"$(LIBDIR)advapi32.lib" >> librsp echo "$(LIBDIR)ole32.lib" >> librsp echo "$(LIBDIR)uuid.lib" >> librsp echo /NODEFAULTLIB:LIBC.lib >> librsp echo "$(LIBDIR)libcmt.lib" >> librsp echo "$(COMPBASE)mfclib afxcw.lib" >> librsp 6.317 Gvwincmak Tekintve, hogy a fő fordítási tevékenységet ez a makefile végzi, az egyes komponensek lefordítását, az object fájlok elkészítését itt kell definiálni. Az OBJS listához hozzáfűztem az új komponenseket (ebből áll elő a gsview32exe), definiáltam a függőségeket a lefordításhoz, az s crypt.cpp fordításához pedig új kapcsolók szükségesek, tekintve, hogy ez a Windows régebbi verzióiban nem elérhető szolgáltatásokat igényel. # # # # # # # # # # # # # # # 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. # Common makefile for BC++ and MSVC++ # See gvwin.mak or gvwinvcmak # Define the location of the WinZip self-extracting-archive-maker. !ifndef WINZIPSE XE WINZIPSE XE="C:Program FilesWinZip Self-ExtractorWZIPSE32.EXE" !endif OBJ1=gvwin.obj gvwddeobj gvwdde2obj gvwdllobj gvwdispobj gvwdlgobj OBJ2=gvwclip.obj gvweditobj gvwepsobj gvwmeasobj gvwmiscobj gvwprfobj OBJ3=gvwprn.obj

gvcmeasobj gvcmeas2obj gvcmiscobj gvcdispobj gvccmdobj OBJ4=gvcprn.obj gvcepsobj gvcinitobj gvctextobj dscparseobj secureobj scardobj scindlg.obj s cryptobj OBJ5=dscutil.obj gvcdllobj gvcpdfobj gvwinitobj gvcbetaobj gvwgsverobj OBJ6=gvcreg.obj gvwregobj gvwfileobj gvwdibobj gvwpdibobj gvwpgdiobj OBJS=$(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5) $(OBJ6) HDRS=gsvver.h gvwinh dscparseh gvcfnh gvcverh gvcfileh gvwdibh gvwpdibh echogsv.exe: echogsvc $(CC) $(CFLAGS) echogsv.c gsvw$(WINEXT)de.res: $(HDRS) gvwin2rc degvclangh degvclangrc degvwlangrc copy degvclang.h gvclangh copy degvclang.rc gvclangrc copy degvwlang.rc gvwlangrc $(RCOMP) -i"$(INCDIR)" -r -fogsvw$(WINEXT)de.res gvwin2 -del gvclang.h -del gvclang.rc -del gvwlang.rc 133 gsvw$(WINEXT)es.res: $(HDRS) gvwin2rc esgvclangh esgvclangrc esgvwlangrc copy esgvclang.h gvclangh copy esgvclang.rc gvclangrc copy esgvwlang.rc gvwlangrc $(RCOMP) -i"$(INCDIR)" -r -fogsvw$(WINEXT)es.res gvwin2 -del gvclang.h -del gvclang.rc

-del gvwlang.rc gsvw$(WINEXT)fr.res: $(HDRS) gvwin2rc frgvclangh frgvclangrc frgvwlangrc copy frgvclang.h gvclangh copy frgvclang.rc gvclangrc copy frgvwlang.rc gvwlangrc $(RCOMP) -i"$(INCDIR)" -r -fogsvw$(WINEXT)fr.res gvwin2 -del gvclang.h -del gvclang.rc -del gvwlang.rc gsvw$(WINEXT)it.res: $(HDRS) gvwin2rc itgvclangh itgvclangrc itgvwlangrc copy itgvclang.h gvclangh copy itgvclang.rc gvclangrc copy itgvwlang.rc gvwlangrc $(RCOMP) -i"$(INCDIR)" -r -fogsvw$(WINEXT)it.res gvwin2 -del gvclang.h -del gvclang.rc -del gvwlang.rc gvwin$(WINEXT).res: $(HDRS) gvwin1rc gvwin2rc engvclangh engvclangrc engvwlangrc copy engvclang.h gvclangh copy engvclang.rc gvclangrc copy engvwlang.rc gvwlangrc $(RCOMP) -i"$(INCDIR)" -r -fogvwin$(WINEXT).res gvwin1 # -del gvclang.h # -del gvclang.rc # -del gvwlang.rc gsprint.obj: gsprintcpp gvcfileh gvwdibh gvwpdibh gsvverh gvcverh scard.obj: scardh scardcpp scindlg.obj: scindlgcpp scindlgh resourceh s crypt.obj: s crypth s

cryptcpp $(CC) -c $(CFLAGS) -D WIN32 WINNT=0x0400 $*.cpp secure.obj: securecpp secureh scardobj scindlgobj s cryptobj gvwin.obj: gvwincpp $(HDRS) gvwclip.obj: gvwclipcpp $(HDRS) gvwdisp.obj: gvwdispcpp $(HDRS) [] 6.318 buildbat Alapvető környezeti változók beállítását végzi az alábbi batchfile, ezekre csak akkor van szükség, ha az alapbeállítások nem megfelelőek, vagy időközben a Visual Studiohoz újabb Platform SDK vagy egyéb komponensek lettek telepítve. Egyébként a Visual Studio 6 alapbeállításként nem támogatja a parancssori fordítást, legalábbis oly módon nem, hogy a környezeti változók értékei nincsenek beállítva. Tulajdonképpen a vcvars32.bat elindítása is sikerre vezethet ilyen esetben, csak sajnos bootolás után nem mindig marad kellő memória a változók beállítására (Out of environmental space), tekintve a vcvars32.bat terjedelmes memóriaigényét a számos temporáris változó miatt rem Change environmental variables

according to your local settings set LIB=D:VISUAL6VC98LIB set INCLUDE=D:VISUAL6VC98INCLUDE;D:VISUAL6VC98MFCINCLUDE nmake 134 7. Az autentikációs állományt létrehozó Cardlist program Visual C++ 6 nyelvű forráskódja A Cardlist tulajdonképpen egy egyszerű listakarbantartó program. Lehetőség van a listához új elemet hozzáadni, abból elemeket törölni, illetve a fájlba mentés és fájlból való betöltésre. A fájlformátum binárisan kódolt A program egy dialógus alapú alkalmazás, melyet teljes egészében a Visual Studio használatával hoztam létre. 7.1 A létrehozott fájlok (20 darab) - Cardlist.dsw a workspace definíciós fájl (egyetlen projektet tartalmaz) - Cardlist.dsp a Cardlist nevű projekt definíciós fájlja - Cardlist.cpp a tulajdonképpeni főprogram - Cardlist.h a hozzá tartozó header fájl - Cardlist.rc a főprogram erőforrás-definíciós fájlja - resource.h konstansdefiníciók az erőforrásokhoz - StdAfx.cpp a

Visual Studio általános előfordított header fájlja - StdAfx.h a hozzá tartozó definíciós fájl - CardlistDlg.cpp a tulajdonképpeni fődialógus-ablak implementációja - CardlistDlg.h a fődialógus-ablak definíciós fájlja - CodeDlg.cpp a PIN kód megadásához szükséges dialógusablak implementációja - CodeDlg.h a hozzá tartozó definíciós fájl - FileCodeDlg.cpp a fájlnév és a dekódolási kulcs megadásának implementációja - FileCodeDlg.h a hozzá tartozó definíciós fájl - Scard.cpp az intelligenskártya-olvasását kezelő osztály megvalósítása - Scard.h az intelligenskártya-olvasását kezelő osztály definíciója - ReadMe.txt rövid leírás a programról - extr.bin autentikációs példafájl - res/Cardlist.rc2 manuálisan szerkeszthető erőforrás-definíció - res/Cardlist.ico a program ikonja Az említett állományok a Cardlist alkönyvtárban találhatók a mellékelt adathordozón. 7.2 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 Cardlist alkönyvtárban találhatók meg 135 7.21 Cardlistdsw A Microsoft Visual C++ 6 által generált fájl, mely a projektek nevét tartalmazza, jelenleg a Cardlist nevű projektet. Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "Cardlist"=.Cardlistdsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### 7.22 Cardlistdsp Szintén automatikusan generált fájl ez a projekt definíciós fájl.

Tartalmaz minden a fordításhoz szükséges információt (nagyon hasonlóan egy makefile-hoz), a fájlok neveit, a megadott csoportosítási szempontokat stb. Jelenleg különösebb módosítások nélkül szerepel # Microsoft Developer Studio Project File - Name="Cardlist" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # * DO NOT EDIT # TARGTYPE "Win32 (x86) Application" 0x0101 CFG=Cardlist - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "Cardlist.mak" !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "Cardlist.mak" CFG="Cardlist - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "Cardlist - Win32 Release"

(based on "Win32 (x86) Application") !MESSAGE "Cardlist - Win32 Debug" (based on "Win32 (x86) Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc ProjName "" # PROP Scc LocalPath "" CPP=cl.exe 136 MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "Cardlist - Win32 Release" # PROP BASE Use MFC 5 # PROP BASE Use Debug Libraries 0 # PROP BASE Output Dir "Release" # PROP BASE Intermediate Dir "Release" # PROP BASE Target Dir "" # PROP Use MFC 5 # PROP Use Debug Libraries 0 # PROP Output Dir "Release" # PROP Intermediate Dir "Release" # PROP Target Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D " WINDOWS" /Yu"stdafx.h" /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D " WINDOWS" /D " MBCS" /Yu"stdafx.h"

/FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x40e /d "NDEBUG" # ADD RSC /l 0x40e /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 # ADD LINK32 /nologo /subsystem:windows /machine:I386 !ELSEIF "$(CFG)" == "Cardlist - Win32 Debug" # PROP BASE Use MFC 5 # PROP BASE Use Debug Libraries 1 # PROP BASE Output Dir "Debug" # PROP BASE Intermediate Dir "Debug" # PROP BASE Target Dir "" # PROP Use MFC 5 # PROP Use Debug Libraries 1 # PROP Output Dir "Debug" # PROP Intermediate Dir "Debug" # PROP Target Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D " DEBUG" /D " WINDOWS" /Yu"stdafx.h" /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX

/ZI /Od /D "WIN32" /D " DEBUG" /D " WINDOWS" /D " MBCS" /Yu"stdafx.h" /FD /GZ /c # ADD BASE MTL /nologo /D " DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D " DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x40e /d " DEBUG" # ADD RSC /l 0x40e /d " DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target # Name "Cardlist - Win32 Release" # Name "Cardlist - Win32 Debug" # Begin Group "Source Files" # PROP Default Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.Cardlistcpp # End Source File # Begin Source File SOURCE=.Cardlistrc # End Source File # Begin Source File SOURCE=.CardlistDlgcpp 137 # End Source File # Begin Source File

SOURCE=.CodeDlgcpp # End Source File # Begin Source File SOURCE=.FileCodeDlgcpp # End Source File # Begin Source File SOURCE=.Scardcpp # End Source File # Begin Source File SOURCE=.StdAfxcpp # ADD CPP /Yc"stdafx.h" # End Source File # End Group # Begin Group "Header Files" # PROP Default Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.Cardlisth # End Source File # Begin Source File SOURCE=.CardlistDlgh # End Source File # Begin Source File SOURCE=.CodeDlgh # End Source File # Begin Source File SOURCE=.FileCodeDlgh # End Source File # Begin Source File SOURCE=.Resourceh # End Source File # Begin Source File SOURCE=.scardh # End Source File # Begin Source File SOURCE=.StdAfxh # End Source File # End Group # Begin Group "Resource Files" # PROP Default Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # Begin Source File SOURCE=. esCardlistico # End Source File # Begin Source File SOURCE=. esCardlistrc2 # End Source File # End

Group # Begin Source File SOURCE=.ReadMetxt # End Source File # End Target # End Project 7.23 Cardlistcpp A megadott programozói szempontok alapján automatikusan generált fájl, a tulajdonképpeni főprogram. Nincs más feladata, mint elindítani CCardlistDlg osztály egy példányát (dlg), és beállítani a megjelenítés tulajdonságait. 138 // Cardlist.cpp : Defines the class behaviors for the application // #include "stdafx.h" #include "Cardlist.h" #include "CardlistDlg.h" #ifdef DEBUG #define new DEBUG NEW #undef THIS FILE static char THIS FILE[] = FILE ; #endif ///////////////////////////////////////////////////////////////////////////// // CCardlistApp BEGIN MESSAGE MAP(CCardlistApp, CWinApp) //{{AFX MSG MAP(CCardlistApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX MSG ON COMMAND(ID HELP, CWinApp::OnHelp) END MESSAGE MAP()

///////////////////////////////////////////////////////////////////////////// // CCardlistApp construction CCardlistApp::CCardlistApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CCardlistApp object CCardlistApp theApp; ///////////////////////////////////////////////////////////////////////////// // CCardlistApp initialization BOOL CCardlistApp::InitInstance() { // 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(); #else Enable3dControlsStatic(); #endif // Call this when using MFC in a shared DLL // Call this when linking to MFC statically CCardlistDlg dlg; m pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { //

TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the applications message pump. return FALSE; } 139 7.24 Cardlisth Szintén automatikusan generált fájl, az előbbi header fájlja, mely a főprogramosztály (CCardlistApp) osztály definícióját tartalmazza. // Cardlist.h : main header file for the CARDLIST application // #if !defined(AFX CARDLIST H 2556EB85 3D24 11D8 90AF 000AE642C6C5 INCLUDED ) #define AFX CARDLIST H 2556EB85 3D24 11D8 90AF 000AE642C6C5 INCLUDED #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 #ifndef AFXWIN H #error include stdafx.h before including this file for PCH #endif #include "resource.h" // main symbols

///////////////////////////////////////////////////////////////////////////// // CCardlistApp: // See Cardlist.cpp for the implementation of this class // class CCardlistApp : public CWinApp { public: CCardlistApp(); // Overrides // ClassWizard generated virtual function overrides //{{AFX VIRTUAL(CCardlistApp) public: virtual BOOL InitInstance(); //}}AFX VIRTUAL // Implementation //{{AFX MSG(CCardlistApp) // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX MSG DECLARE MESSAGE MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX CARDLIST H 2556EB85 3D24 11D8 90AF 000AE642C6C5 INCLUDED ) 7.25 Cardlistrc A Visual Studio varázslója segítségével készített fájl. 4 dialógusablakot definiál többek között, a fő

dialógusablakot, mely a lista megjelenítésére szolgál, egy AboutBoxot, egy PIN kód bekérő ablakot figyelmeztetéssel a hibás próbálkozások következményeire, valamint egy fájlnév és kódolási kulcs megadására szolgáló dialógusablakot. A kulcsot kétszer kell megadni, a tévesztés elkerülése végett. //Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO READONLY SYMBOLS ///////////////////////////////////////////////////////////////////////////// 140 // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO READONLY SYMBOLS ///////////////////////////////////////////////////////////////////////////// // Hungarian resources #if !defined(AFX RESOURCE DLL) || defined(AFX TARG HUN) #ifdef WIN32 LANGUAGE LANG HUNGARIAN, SUBLANG DEFAULT #pragma code page(1250) #endif // WIN32 #ifdef APSTUDIO

INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h"" " "" END 3 TEXTINCLUDE DISCARDABLE BEGIN "#define AFX NO SPLITTER RESOURCES " "#define AFX NO OLE RESOURCES " "#define AFX NO TRACKER RESOURCES " "#define AFX NO PROPERTY RESOURCES " " " "#if !defined(AFX RESOURCE DLL) || defined(AFX TARG ENU) " "#ifdef WIN32 " "LANGUAGE 9, 1 " "#pragma code page(1252) " "#endif // WIN32 " "#include ""res\Cardlist.rc2"" // non-Microsoft Visual C++ edited resources " "#include ""afxres.rc"" // Standard components " "#endif " "" END #endif // APSTUDIO INVOKED

///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDR MAINFRAME ICON DISCARDABLE "res\Cardlist.ico" ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55 STYLE DS MODALFRAME | WS POPUP | WS CAPTION | WS SYSMENU CAPTION "About Cardlist" FONT 8, "MS Sans Serif" BEGIN ICON IDR MAINFRAME,IDC STATIC,11,17,20,20 LTEXT "Cardlist Editor Version 1.0",IDC STATIC,40,10,119,8, SS NOPREFIX 141 LTEXT DEFPUSHBUTTON "Copyright (C) 2004 Petty",IDC STATIC,40,25,77,8 "OK",IDOK,178,7,50,14,WS GROUP END IDD CARDLIST DIALOG DIALOGEX 0, 0, 214, 188 STYLE DS MODALFRAME | WS POPUP | WS VISIBLE | WS CAPTION | WS SYSMENU EXSTYLE WS EX APPWINDOW CAPTION "Cardlist" FONT 8, "MS Sans Serif" BEGIN

DEFPUSHBUTTON "End",IDOK,157,167,50,14 PUSHBUTTON "Add",IDC ADD,7,167,50,14 PUSHBUTTON "Load",IDC READLIST,57,167,50,14 PUSHBUTTON "Save",IDC SAVELIST,107,167,50,14 CONTROL "List1",IDC LIST1,"SysListView32",LVS REPORT | WS BORDER | WS TABSTOP,7,7,200,155 END IDD DIALOGCODE DIALOG DISCARDABLE 0, 0, 120, 75 STYLE DS MODALFRAME | WS POPUP | WS CAPTION | WS SYSMENU CAPTION "Enter PIN Code" FONT 8, "MS Sans Serif" BEGIN EDITTEXT IDC EDITCODE,7,40,106,14,ES PASSWORD | ES NUMBER DEFPUSHBUTTON "OK",IDOK,63,56,50,14 PUSHBUTTON "Cancel",IDCANCEL,7,56,50,14 LTEXT "Please enter your PIN code. Invalid PIN code can damage your SIM!", IDC STATIC,7,7,106,32 END IDD DIALOGFILECODE DIALOG DISCARDABLE 0, 0, 114, 109 STYLE DS MODALFRAME | WS POPUP | WS CAPTION | WS SYSMENU CAPTION "File" FONT 8, "MS Sans Serif" BEGIN EDITTEXT IDC EDIT1,7,15,100,14,ES AUTOHSCROLL EDITTEXT IDC

EDIT2,7,42,100,14,ES PASSWORD EDITTEXT IDC EDIT3,7,69,100,14,ES PASSWORD DEFPUSHBUTTON "OK",IDOK,57,88,50,14 PUSHBUTTON "Cancel",IDCANCEL,7,88,50,14 LTEXT "Filename",IDC STATIC,7,7,100,8 LTEXT "Password",IDC STATIC,7,34,100,8 LTEXT "Confirm password",IDC STATIC,7,61,100,8 END ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD ABOUTBOX, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 228 TOPMARGIN, 7 BOTTOMMARGIN, 48 END IDD CARDLIST DIALOG, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 207 TOPMARGIN, 7 BOTTOMMARGIN, 181 END IDD DIALOGCODE, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 106 TOPMARGIN, 7 BOTTOMMARGIN, 70 END 142 IDD DIALOGFILECODE, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 107 TOPMARGIN, 7 BOTTOMMARGIN, 102 END END #endif // APSTUDIO INVOKED #endif // Hungarian resources

///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // English (U.S) resources #if !defined(AFX RESOURCE DLL) || defined(AFX TARG ENU) #ifdef WIN32 LANGUAGE LANG ENGLISH, SUBLANG ENGLISH US #pragma code page(1252) #endif // WIN32 #ifndef MAC ///////////////////////////////////////////////////////////////////////////// // // Version // VS VERSION INFO VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL #ifdef DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904B0" BEGIN VALUE "CompanyName", "" VALUE "FileDescription", "Cardlist MFC Application" VALUE "FileVersion", "1, 0, 0, 1" VALUE "InternalName", "Cardlist" VALUE "LegalCopyright", "Copyright (C)

2004" VALUE "LegalTrademarks", "" VALUE "OriginalFilename", "Cardlist.EXE" VALUE "ProductName", "Cardlist Application" VALUE "ProductVersion", "1, 0, 0, 1" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #endif // ! MAC ///////////////////////////////////////////////////////////////////////////// // // String Table // STRINGTABLE DISCARDABLE BEGIN IDS ABOUTBOX END "&About Cardlist." 143 #endif // English (U.S) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // #define AFX NO SPLITTER RESOURCES #define AFX NO OLE RESOURCES #define AFX NO TRACKER RESOURCES #define AFX NO PROPERTY RESOURCES #if !defined(AFX RESOURCE DLL) || defined(AFX

TARG ENU) #ifdef WIN32 LANGUAGE 9, 1 #pragma code page(1252) #endif // WIN32 #include "resCardlist.rc2" // non-Microsoft Visual C++ edited resources #include "afxres.rc" // Standard components #endif ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO INVOKED 7.26 resourceh A ClassWizard segítségével lett létrehozva ez a konstansdefiníciós fájl, mely a program által lekezelendő üzenetek azonosítóit és a dialógusablak-kontrollok azonosítóit tartalmazza. //{{NO DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by Cardlist.rc // #define IDM ABOUTBOX 0x0010 #define IDD ABOUTBOX 100 #define IDS ABOUTBOX 101 #define IDD CARDLIST DIALOG 102 #define IDR MAINFRAME 128 #define IDD DIALOGCODE 129 #define IDD DIALOGFILECODE 130 #define IDC EDIT1 1000 #define IDC READLIST 1001 #define IDC SAVELIST 1002 #define IDC ADD 1004 #define IDC EDIT2 1005 #define IDC EDITCODE 1007 #define IDC

EDIT3 1032 #define IDC LIST1 1035 #define IDC REMOVE 1036 // Next default values for new objects // #ifdef APSTUDIO INVOKED #ifndef APSTUDIO READONLY SYMBOLS #define APS NEXT RESOURCE VALUE #define APS NEXT COMMAND VALUE #define APS NEXT CONTROL VALUE #define APS NEXT SYMED VALUE #endif #endif 131 32771 1037 101 7.27 StadAfxcpp Az előfordított header fájl üres implementációja. Jelenleg használaton kívül van, a Visual Studio automatikusan hozta létre. Mindenképpen érdemes meghagyni, ha el akarjuk kerülni a projekt fájl kézzel történő módosítását, valamint minden temporáris fájl törlését, majd az azt követő, igaz immár automatikus újralétrehozását. 144 // stdafx.cpp : source file that includes just the standard includes // Cardlist.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" 7.28 StdAfxh Az előbbi fájl header fájlja kiegészítve két, a fájlrendszer

kezelését támogató #include makróval. Ezekre ugyanis később szükség van a fájlok betöltésénél, illetve mentésénél, tekintve azonban, hogy a StdAfx.h fájlt minden implementációs állomány „include”-olja célszerű itt elvégezni. (<fstreamh>, <iostreamh>) // stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX STDAFX H 2556EB89 3D24 11D8 90AF 000AE642C6C5 INCLUDED ) #define AFX STDAFX H 2556EB89 3D24 11D8 90AF 000AE642C6C5 INCLUDED #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 #define VC EXTRALEAN // Exclude rarely-used stuff from Windows headers #include <fstream.h> #include <iostream.h> #include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls #ifndef AFX NO

AFXCMN SUPPORT #include <afxcmn.h> // MFC support for Windows Common Controls #endif // AFX NO AFXCMN SUPPORT //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX STDAFX H 2556EB89 3D24 11D8 90AF 000AE642C6C5 INCLUDED ) 7.29 CardlistDlgcpp A fő dialógusablak megvalósítása, valamint az AboutBox-é. Jelen esetben talán érdemesebb a CardlistDlgh állomány tanulmányozásával kezdeni a forráskód megértését, tekintve az alábbi állomány 22 kilobájtos méretét. A <wincrypt.h> használatára az implementációfüggetlenül azonos végeredményt produkáló kódolás miatt van szükség, mint ahogy láthatjuk is, ezt a kódolási algoritmus megadása követi. A konstruktorok csak a szokásos műveleteket végzik, az OnInitDialog() viszont a megszokottakon kívül törli a nyilvános változók értékét, s létrehozza a megjelenítést végző CListCtrl osztály

adott példányának „#”, a „Serial number” és „IMSI” oszlopait. A kilépés előtti utolsó pillanatokban hívódik meg az OnClose() függvény, melynek célja, hogy az esetleges változtatások elmentésére rákérdezzen a changed változó értéke alapján. 145 A ClearFile(FILE *fhandler) az esetlegesen, valamilyen hiba miatt félbehagyott mentés közben keletkezett állomány tartalmát törli, tekintve, hogy az használhatatlan, ha nem sikerült a kódolás végére érni. Az OnReadlist() és OnSavelist() lényegében hasonlóan működnek. Mindkettő a CFileCodeDlg osztály egy példányát létrehozva bekéri a fájl nevét és a kódolás kulcsát. Csak az egyik a ListControlból veszi az elemeket, míg a másik épp azt tölti fel A kódolás menete egyébként megegyezik a GSView.exe forráskódjában szereplővel, így ezt itt nem részletezném. A műveletek sikeres elvégzését a betöltésnél az immár új lista jelzi, míg elmentésnél egy, a

sikeres mentést jelző MessageBox. Az OnAdd() függvény a kártya sorszámát és IMSI számát kéri be, és teszi a lista végére. A mechanizmus megegyezik a GSViewexe forráskódjában szereplővel, csak itt a beolvasott értéket a lista végére fűzzük Az OnRemove() függvény a listában kiválasztott sorszámú sor, vagy sorok törlését végzi, majd újrasorszámozza az immár foghíjas listát. // CardlistDlg.cpp : implementation file // #include #include #include #include #include "stdafx.h" "Cardlist.h" "CardlistDlg.h" "FileCodeDlg.h" "CodeDlg.h" //cryptographic functions #include <wincrypt.h> // defines for RC4 stream cipher #define ENCRYPT ALGORITHM CALG RC4 #define ENCRYPT BLOCK SIZE 1 //smartcard functions #include "scard.h" #ifdef DEBUG #define new DEBUG NEW #undef THIS FILE static char THIS FILE[] = FILE ; #endif ///////////////////////////////////////////////////////////////////////////// //

CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX DATA(CAboutDlg) enum { IDD = IDD ABOUTBOX }; //}}AFX DATA // ClassWizard generated virtual function overrides //{{AFX VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX VIRTUAL // Implementation protected: //{{AFX MSG(CAboutDlg) //}}AFX MSG DECLARE MESSAGE MAP() }; 146 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX DATA INIT(CAboutDlg) //}}AFX DATA INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX DATA MAP(CAboutDlg) //}}AFX DATA MAP } BEGIN MESSAGE MAP(CAboutDlg, CDialog) //{{AFX MSG MAP(CAboutDlg) // No message handlers //}}AFX MSG MAP END MESSAGE MAP() ///////////////////////////////////////////////////////////////////////////// // CCardlistDlg dialog CCardlistDlg::CCardlistDlg(CWnd* pParent /=NULL/) : CDialog(CCardlistDlg::IDD, pParent) { //{{AFX DATA

INIT(CCardlistDlg) //}}AFX DATA INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m hIcon = AfxGetApp()->LoadIcon(IDR MAINFRAME); } void CCardlistDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX DATA MAP(CCardlistDlg) //}}AFX DATA MAP } BEGIN MESSAGE MAP(CCardlistDlg, CDialog) //{{AFX MSG MAP(CCardlistDlg) ON WM SYSCOMMAND() ON WM PAINT() ON WM QUERYDRAGICON() ON BN CLICKED(IDC READLIST, OnReadlist) ON BN CLICKED(IDC SAVELIST, OnSavelist) ON BN CLICKED(IDC ADD, OnAdd) ON WM CLOSE() ON BN CLICKED(IDC REMOVE, OnRemove) //}}AFX MSG MAP END MESSAGE MAP() ///////////////////////////////////////////////////////////////////////////// // CCardlistDlg message handlers BOOL CCardlistDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About." menu item to system menu // IDM ABOUTBOX must be in the system command range. ASSERT((IDM ABOUTBOX & 0xFFF0) == IDM ABOUTBOX); ASSERT(IDM ABOUTBOX < 0xF000); CMenu* pSysMenu =

GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF SEPARATOR); pSysMenu->AppendMenu(MF STRING, IDM ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically 147 // when the applications main window is not a dialog SetIcon(m hIcon, TRUE); // Set big icon SetIcon(m hIcon, FALSE); // Set small icon // TODO: Add extra initialization here changed=FALSE; CodeNum=""; //Set ListCtrl CListCtrl *lc=(CListCtrl)GetDlgItem(IDC LIST1); lc->InsertColumn(0, "#", LVCFMT RIGHT, 50, 50); lc->InsertColumn(1, "Serial number", LVCFMT LEFT, 163, 163); lc->InsertColumn(2, "IMSI", LVCFMT LEFT, 163, 163); return TRUE; // return TRUE unless you set the focus to a control } void CCardlistDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM ABOUTBOX) { CAboutDlg dlgAbout;

dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CCardlistDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM CXICON); int cyIcon = GetSystemMetrics(SM CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CCardlistDlg::OnQueryDragIcon() { return (HCURSOR) m hIcon; } void CCardlistDlg::OnClose() { // TODO: Add your message handler code here

and/or call default if (changed) {//Editbox changed? if (IDYES==MessageBox("The content of Listbox has changed. Save?", "Save?", MB YESNO)) { OnSavelist(); } } 148 CDialog::OnClose(); } //Erase file in case of bad input etc. void CCardlistDlg::ClearFile(FILE *fhandler) { fclose(fhandler); fhandler=fopen(Fname,"w+b"); //open and erase file fclose(fhandler); } void CCardlistDlg::OnReadlist() { // TODO: Add your control notification handler code here int i; int length; CString rstring(""); CString qstring(""); FILE *fhandler; CListCtrl *lc=(CListCtrl)GetDlgItem(IDC LIST1); unsigned char szPassw[255];// = PASSWORD; unsigned int szPasswlen;// = PASSWORDLEN; CodeNum=""; Fname[0]=; //Get data from user CFileCodeDlg FCdlg; FCdlg.pardlg=this; //pointer to this class //return values in CodeNum and Fname int nResponse = FCdlg.DoModal(); if (nResponse == IDOK) { for (i=0; i<8; i++) szPassw[i]=; for (i=0;

i<CodeNum.GetLength(); i++) { szPassw[i]=CodeNum[i]; } szPasswlen=CodeNum.GetLength(); } else { return; } if (Fname[0]!=) { if (NULL==(fhandler=fopen(Fname,"rb"))) //open file { MessageBox("Unable to open file","Error"); return; } if (ferror(fhandler)) { MessageBox("Unable to read from file","Error"); return; } } else return; //Hash functions HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; int eof = 0; unsigned char pbBuffer[255]; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount; //string for decoding //Decode file with a unique key producing from user input // Get handle to the CL1 provider 149 if (!CryptAcquireContext(&hProv, "CL1", MS DEF PROV, PROV RSA FULL, 0)) { DWORD errt=GetLastError(); if (errt==NTE BAD KEYSET) {//if not exist in registry then create a new one if (!CryptAcquireContext(&hProv, "CL1", MS DEF PROV, PROV RSA FULL, CRYPT NEWKEYSET)) { MessageBox("Unable

to access Crypto API","Error"); return; } } else { MessageBox("Unable to decrypt file","Error"); return; } } // Create a hash object if (!CryptCreateHash(hProv, CALG MD5, 0, 0, &hHash)) { MessageBox("Unable to decrypt file","Error"); return; } // Hash in the password data if (!CryptHashData(hHash, szPassw, szPasswlen, 0)) { MessageBox("Unable to decrypt file","Error"); return; } // Derive a session key from the hash object if (!CryptDeriveKey(hProv, ENCRYPT ALGORITHM, hHash, 0, &hKey)) { MessageBox("Unable to decrypt file","Error"); return; } // Destroy the hash object. CryptDestroyHash(hHash); hHash = 0; //Read about 100 bytes in a block // Determine number of bytes to encrypt at a time. This must be a multiple // of ENCRYPT BLOCK SIZE. dwBlockLen = 100 - 100 % ENCRYPT BLOCK SIZE; dwBufferLen = dwBlockLen; rstring=""; //Begin decoding do { qstring=""; // Read up

to dwBlockLen bytes from source file dwCount = fread(pbBuffer, 1, dwBlockLen, fhandler); if(ferror(fhandler)) { MessageBox("Unable to read from file","Error"); return; } eof = feof(fhandler); // Decrypt data if(!CryptDecrypt(hKey, 0, eof, 0, pbBuffer, &dwCount)) { MessageBox("Unable to decrypt file","Error"); return; } //data in pbBuffer: from last block to first block for (i=0; (unsigned int)i<dwCount; i++) { qstring+=pbBuffer[i]; } qstring+=rstring; rstring=qstring; 150 } while(!feof(fhandler)); //Free memory // Destroy session key. if(hKey) CryptDestroyKey(hKey); // Destroy hash object. if(hHash) CryptDestroyHash(hHash); // Release provider handle. if(hProv) CryptReleaseContext(hProv, 0); //lines from two columns are altered length=rstring.GetLength(); int c=0; int row=0; char tnum[30]; lc->DeleteAllItems(); while (c<length) { sprintf(tnum, "%d", row+1); lc->InsertItem(row, tnum); for (i=0; i<20; i++)

tnum[i]=rstring[c+i]; tnum[i]=; lc->SetItemText(row, 1, tnum); c+=20; for (i=0; i<15; i++) tnum[i]=rstring[c+i]; tnum[i]=; lc->SetItemText(row, 2, tnum); c+=15; row++; } //end fclose(fhandler); //success changed=FALSE; } void CCardlistDlg::OnSavelist() { // TODO: Add your control notification handler code here int i,j; char egysor[255]; int length; CListCtrl *lc=(CListCtrl)GetDlgItem(IDC LIST1); int last=lc->GetItemCount(); //index of last row CString rstring(""); CString qstring(""); CString sstring(""); FILE *fhandler; char tmp; unsigned char szPassw[255];// = PASSWORD; unsigned int szPasswlen;// = PASSWORDLEN; CodeNum=""; Fname[0]=; //Get data from user CFileCodeDlg FCdlg; FCdlg.pardlg=this; //pointer to this class //return values in CodeNum and Fname int nResponse = FCdlg.DoModal(); if (nResponse == IDOK) { for (i=0; i<8; i++) szPassw[i]=; for (i=0; i<CodeNum.GetLength(); i++) { szPassw[i]=CodeNum[i]; 151 }

szPasswlen=CodeNum.GetLength(); } else { return; } if (Fname[0]!=) { if (NULL==(fhandler=fopen(Fname,"wb"))) //open file { MessageBox("Unable to open file","Error"); return; } if (ferror(fhandler)) { MessageBox("Unable to write to file","Error"); ClearFile(fhandler); return; } } else return; //Hash functions HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; int eof = 0; unsigned char pbBuffer[255]; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount; //string for encoding //Check //read data from ListCtrl for (i=0; i<last; i++) { rstring=lc->GetItemText(i, 1); //serial number if (rstring.GetLength()!=20) {//error MessageBox("Serial number of card contains 20 digits or 19 digits plus character F.", "Error"); ClearFile(fhandler); return; } for (j=0; j<(rstring.GetLength())-1; j++) { if ((rstring[j]<0)||(9<rstring[j])) { MessageBox("Serial number of card contains only decimal digits

and character F or f.", "Error"); ClearFile(fhandler); return; } } if (((rstring[j]<0)||(9<rstring[j]))&&(rstring[j]!=f)&&(rstring[j]!=F)) { MessageBox("Serial number of card contains only decimal digits and character F or f.", "Error"); ClearFile(fhandler); return; } } //second //read data from ListCtrl rstring=""; for (i=0; i<last; i++) { rstring+=lc->GetItemText(i, 2); rstring+=" "; } length=rstring.GetLength(); 152 j=0; for (i=0; i<length; i++) { if ((rstring[i]!= )&&(rstring[i]!= )) { tmp=rstring[i]; if ((0<=tmp)&&(tmp<=9)) {//acceptable character egysor[j++]=tmp; } else { MessageBox("IMSI contains only decimal digits.", "Error"); ClearFile(fhandler); return; } if (j>15) //error { MessageBox("IMSI contains 15 digits or less digits and unused characters shall be set to 0.", "Error"); ClearFile(fhandler); return; } } else {//end

of line if ((j!=15)&&(j!=0)) //error { MessageBox("IMSI contains 15 digits or less digits and unused characters shall be set to 0.", "Error"); ClearFile(fhandler); return; } j=0; } } //end if ((j!=15)&&(j!=0)) //error { MessageBox("IMSI contains 15 digits or less digits and unused characters shall be set to 0.", "Error"); ClearFile(fhandler); return; } //Encode file with a unique key producing from user input // Get handle to the default provider. if (!CryptAcquireContext(&hProv, "CL1", MS DEF PROV, PROV RSA FULL, 0)) { DWORD errt=GetLastError(); if (errt==NTE BAD KEYSET) {//if not exist in registry then create a new one if (!CryptAcquireContext(&hProv, "CL1", MS DEF PROV, PROV RSA FULL, CRYPT NEWKEYSET)) { MessageBox("Unable to access registry","Error"); ClearFile(fhandler); return; } } else { MessageBox("Unable to encrypt file","Error"); ClearFile(fhandler);

return; } } // Create a hash object. if (!CryptCreateHash(hProv, CALG MD5, 0, 0, &hHash)) { MessageBox("Unable to encrypt file","Error"); ClearFile(fhandler); return; } // Hash in the password data. 153 if (!CryptHashData(hHash, szPassw, szPasswlen, 0)) { MessageBox("Unable to encrypt file","Error"); ClearFile(fhandler); return; } // Derive a session key from the hash object. if (!CryptDeriveKey(hProv, ENCRYPT ALGORITHM, hHash, 0, &hKey)) { MessageBox("Unable to encrypt file","Error"); ClearFile(fhandler); return; } // Destroy the hash object. CryptDestroyHash(hHash); hHash = 0; //Write about 100 bytes in a block // Determine number of bytes to encrypt at a time. This must be a multiple // of ENCRYPT BLOCK SIZE. dwBlockLen = 100 - 100 % ENCRYPT BLOCK SIZE; // Determine the block size. If a block cipher is used this must have // room for an extra block. if (ENCRYPT BLOCK SIZE > 1) { dwBufferLen = dwBlockLen +

ENCRYPT BLOCK SIZE; } else { dwBufferLen = dwBlockLen; } ////lines from two columns are altered //read data from ListCtrl sstring=""; for (i=0; i<last; i++) { sstring+=lc->GetItemText(i, 1); sstring+=" "; } int l1=sstring.GetLength(); int l2=rstring.GetLength(); int c1=0; int c2=0; qstring=""; while ((c1<l1)&&(c2<l2)) { qstring+=sstring.Mid(c1,20); qstring+=rstring.Mid(c2,15); c1+=22; c2+=17; } length=qstring.GetLength(); //Begin encoding do { // Read up to dwBlockLen bytes if ((unsigned int)length<dwBlockLen) { dwCount=length; length=0; } else { dwCount=dwBlockLen; length-=dwBlockLen; } //data in pbBuffer: from last block to first block for (i=0; (unsigned int)i<dwCount; i++) { pbBuffer[i]=qstring[length+i]; } 154 pbBuffer[i]=; //last block? eof=!length; // Encrypt data if (!CryptEncrypt(hKey, 0, eof, 0, pbBuffer, &dwCount, dwBufferLen)) { MessageBox("Unable to encrypt file","Error");

ClearFile(fhandler); return; } // Write data to destination file. fwrite(pbBuffer, 1, dwCount, fhandler); if(ferror(fhandler)) { MessageBox("Unable to write to file","Error"); ClearFile(fhandler); return; } } while(!eof); //free memory // Destroy session key. if(hKey) CryptDestroyKey(hKey); // Destroy hash object. if(hHash) CryptDestroyHash(hHash); // Release provider handle. if(hProv) CryptReleaseContext(hProv, 0); fclose(fhandler); //success MessageBox("File successfully saved.", "Saved"); changed=FALSE; } void CCardlistDlg::OnAdd() {//add the serial number and IMSI of current smartcard to the list // TODO: Add your control notification handler code here CScard card; char serial[100]; char imsi[100]; int i; Error myError; char buf[255]; for (i=0; i<255; i++) buf[i]=0; CListCtrl *lc=(CListCtrl)GetDlgItem(IDC LIST1); //Smartcard init myError=card.Init(); if(myError) { card.GetErrText(buf); MessageBox(buf,"Error",MB OK); return; }

//Environmental settings char nyelv[20]="ENGLISH"; if(myError=card.SetLng(nyelv)){ MessageBox("Selected language not available", "Error", MB OK); } //Serial number //Information from card char DataOut[12]={0}; char FileID[2]={0x3f,0x00}; //Select MasterFile char Statuserr[32]={0}; //Select root if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ card.GetErrText(buf); 155 MessageBox(buf,"Error",MB OK); return; } if (0x9f!=(unsigned char)DataOut[0]) { //Not available MessageBox("Unknown error", "Error", MB OK); return; } //Select ICC-ID FileID[0]=0x2f; FileID[1]=0xe2; //Select file containing serial number if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ card.GetErrText(buf); MessageBox(buf,"Error",MB OK); return; } if (0x9f!=(unsigned char)DataOut[0]) { MessageBox("Unknown error", "Error", MB OK); return; } //format of file: binary if(myError=card.ReadBinary(10,

DataOut, sizeof(DataOut))){ card.GetErrText(buf); MessageBox(buf,"Error",MB OK); return; } if ((0x90!=(unsigned char)DataOut[0])||(0x00!=(unsigned char)DataOut[1])) { MessageBox("Unknown error", "Error", MB OK); 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); } //IMSI //Information from card //Select MasterFile FileID[0]=0x3f; FileID[1]=0x00; //Select root if(myError=card.SelectFile(FileID, DataOut, card.GetErrText(buf); MessageBox(buf,"Error",MB OK); return; } if (0x9f!=(unsigned char)DataOut[0]) { //Not available MessageBox("Unknown error", "Error", return; } //Select directory GSM FileID[0]=0x7f; FileID[1]=0x20; //Select directory GSM if(myError=card.SelectFile(FileID, DataOut, card.GetErrText(buf);

MessageBox(buf,"Error",MB OK); return; } if (0x9f!=(unsigned char)DataOut[0]) { //Not available MessageBox("Unknown error", "Error", return; } //Select IMSI FileID[0]=0x6f; 156 sizeof(DataOut))){ MB OK); sizeof(DataOut))){ MB OK); FileID[1]=0x07; //Select file containing IMSI if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ card.GetErrText(buf); MessageBox(buf,"Error",MB OK); return; } if (0x9f!=(unsigned char)DataOut[0]) { MessageBox("Ismeretlen hiba!", "Error", MB OK); return; } //format of file: binary if(myError=card.ReadBinary(9, DataOut, sizeof(DataOut))){ card.GetErrText(buf); MessageBox(buf,"Error",MB OK); return; } if ((0x98==(unsigned char)DataOut[0])||(0x04==(unsigned char)DataOut[1])) {//need PIN code CCodeDlg Codedlg; Codedlg.pardlg=this; //pointer to this class //return value in CodeNum int nResponse = Codedlg.DoModal(); if (nResponse == IDOK) { //check PIN code int i; char

Temppin[8]; for(i=0; i<8; i++) Temppin[i]=0xff; for (i=0; i<CodeNum.GetLength(); i++) { Temppin[i]=CodeNum[i]; } //check if(myError=card.VerifyPin(1, Temppin, DataOut, sizeof(DataOut))){ card.GetErrText(buf); MessageBox(buf,"Error",MB OK); return; } if ((0x90!=(unsigned char)DataOut[0])||(0x00!=(unsigned char)DataOut[1])) { MessageBox("Invalid PIN code","Checking PIN",MB OK); return; } } else if (nResponse == IDCANCEL) { MessageBox("You must enter your PIN code to get content of card!","Error",MB OK); return; } //content of file: binary if(myError=card.ReadBinary(9, DataOut, sizeof(DataOut))){ card.GetErrText(buf); MessageBox(buf,"Error",MB OK); return; } } if ((0x90!=(unsigned char)DataOut[0])||(0x00!=(unsigned char)DataOut[1])) { MessageBox("Unknown error", "Error", MB OK); 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++) 157 { //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); } //Add to the content of ListCtrl int last=lc->GetItemCount(); //index of last row char num[5]; sprintf(num, "%d", last+1); lc->InsertItem(last, num); lc->SetItemText(last, 1, serial); lc->SetItemText(last, 2, imsi); changed=TRUE; } void CCardlistDlg::OnRemove() { // remove selected items int i; CString rstring(""); CListCtrl *lc=(CListCtrl)GetDlgItem(IDC LIST1); int last=lc->GetItemCount(); int selmark=lc->GetSelectionMark(); //begin selected region if (selmark<0) return; //no rows selected unsigned int selcnt=lc->GetSelectedCount(); //height of selected region for (i=0; i<(int)selcnt; i++) { lc->DeleteItem(selmark+i); } ////lines from two columns are

altered //read data from ListCtrl rstring=""; for (i=0; i<last; i++) { rstring+=lc->GetItemText(i, 1); rstring+=lc->GetItemText(i, 2); } //lines from two columns are altered int length=rstring.GetLength(); int c=0; int row=0; char tnum[30]; lc->DeleteAllItems(); while (c<length) { sprintf(tnum, "%d", row+1); lc->InsertItem(row, tnum); for (i=0; i<20; i++) tnum[i]=rstring[c+i]; tnum[i]=; lc->SetItemText(row, 1, tnum); c+=20; for (i=0; i<15; i++) tnum[i]=rstring[c+i]; tnum[i]=; lc->SetItemText(row, 2, tnum); c+=15; row++; } //end } 7.210 CardlistDlgh A rengetegféle üzenet lekezelésén túl a fő dialógusablak(osztály) definíciós fájlja többek között, tartalmazza a nyilvános CodeNum és Fname nevű változók definícióját. 158 Ezekre azért van szükség, hogy a gyermekablakok miután lekérdezték ezeknek a változóknak az értékét, könnyedén módosíthassák azt. Hiszen ehhez nem kell más, csak átadni az

osztályra mutató pointert // CardlistDlg.h : header file // #if !defined(AFX CARDLISTDLG H 2556EB87 3D24 11D8 90AF 000AE642C6C5 INCLUDED ) #define AFX CARDLISTDLG H 2556EB87 3D24 11D8 90AF 000AE642C6C5 INCLUDED #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 ///////////////////////////////////////////////////////////////////////////// // CCardlistDlg dialog class CCardlistDlg : public CDialog { // Construction public: CCardlistDlg(CWnd* pParent = NULL); CString CodeNum; char Fname[255]; void ClearFile(FILE* fhandler); // standard constructor // Dialog Data //{{AFX DATA(CCardlistDlg) enum { IDD = IDD CARDLIST DIALOG }; //}}AFX DATA // ClassWizard generated virtual function overrides //{{AFX VIRTUAL(CCardlistDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX VIRTUAL // Implementation protected: int changed; HICON m hIcon; // Generated message map functions //{{AFX MSG(CCardlistDlg) virtual BOOL OnInitDialog(); afx msg

void OnSysCommand(UINT nID, LPARAM lParam); afx msg void OnPaint(); afx msg HCURSOR OnQueryDragIcon(); afx msg void OnReadlist(); afx msg void OnSavelist(); afx msg void OnAdd(); afx msg void OnClose(); afx msg void OnRemove(); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX CARDLISTDLG H 2556EB87 3D24 11D8 90AF 000AE642C6C5 INCLUDED ) 7.211 CodeDlgcpp Egyszerű dialógusosztályt megvalósító fájl. Egyetlen említésre méltó momentum, hogy a „OK” gomb megnyomásakor a titkosított EditBox tartalma a már említett hatásmechanizmussal a CCardlistDlg futó példányának nyilvános CodeNum változójába kerül. // CodeDlg.cpp : implementation file // 159 #include "stdafx.h" #include "Cardlist.h" #include "CodeDlg.h" #ifdef DEBUG #define new DEBUG NEW #undef THIS FILE static char THIS FILE[] = FILE ;

#endif ///////////////////////////////////////////////////////////////////////////// // CCodeDlg dialog CCodeDlg::CCodeDlg(CWnd* pParent /=NULL/) : CDialog(CCodeDlg::IDD, pParent) { //{{AFX DATA INIT(CCodeDlg) m Number = T(""); //}}AFX DATA INIT } void CCodeDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX DATA MAP(CCodeDlg) DDX Control(pDX, IDC EDITCODE, m NumberEdit); DDX Text(pDX, IDC EDITCODE, m Number); DDV MaxChars(pDX, m Number, 8); //}}AFX DATA MAP } BEGIN MESSAGE MAP(CCodeDlg, CDialog) //{{AFX MSG MAP(CCodeDlg) //}}AFX MSG MAP END MESSAGE MAP() ///////////////////////////////////////////////////////////////////////////// // CCodeDlg message handlers void CCodeDlg::OnOK() { // TODO: Add extra validation here //return input if entered enough characters if (4 > GetDlgItemText(IDC EDITCODE,pardlg->CodeNum)) return; CDialog::OnOK(); } 7.212 CodeDlgh Az iménti fájl definícióit tartalmazza, a szükséges változók deklarálása

történik. #if !defined(AFX CODEDLG H ECEDE824 42C3 11D8 90AF 000AE642C6C5 INCLUDED ) #define AFX CODEDLG H ECEDE824 42C3 11D8 90AF 000AE642C6C5 INCLUDED #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 #include "CardlistDlg.h" // CodeDlg.h : header file // ///////////////////////////////////////////////////////////////////////////// // CCodeDlg dialog class CCodeDlg : public CDialog { // Construction public: CCodeDlg(CWnd* pParent = NULL); // standard constructor 160 CCardlistDlg *pardlg; //parent dialog // Dialog Data //{{AFX DATA(CCodeDlg) enum { IDD = IDD DIALOGCODE }; CEdit m NumberEdit; CString m Number; //}}AFX DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX VIRTUAL(CCodeDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX VIRTUAL // Implementation protected: // Generated message map functions //{{AFX MSG(CCodeDlg) virtual void OnOK(); //}}AFX MSG DECLARE MESSAGE MAP()

}; //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX CODEDLG H ECEDE824 42C3 11D8 90AF 000AE642C6C5 INCLUDED ) 7.213 FileCodeDlgcpp Teljesen hasonlóan az előzőekhez ez is egy újabb dialógusosztály megvalósítása, itt a fájlnevet és a kulcsot, valamint ellenőrzősként újra a kulcsot kéri be, az utóbbiakat természetesen titkosítva. // FileCodeDlg.cpp : implementation file // #include "stdafx.h" #include "Cardlist.h" #include "FileCodeDlg.h" #ifdef DEBUG #define new DEBUG NEW #undef THIS FILE static char THIS FILE[] = FILE ; #endif ///////////////////////////////////////////////////////////////////////////// // CFileCodeDlg dialog CFileCodeDlg::CFileCodeDlg(CWnd* pParent /=NULL/) : CDialog(CFileCodeDlg::IDD, pParent) { //{{AFX DATA INIT(CFileCodeDlg) m Filename = T(""); m Password = T(""); m Confpassw =

T(""); //}}AFX DATA INIT } void CFileCodeDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX DATA MAP(CFileCodeDlg) DDX Control(pDX, IDC EDIT3, m ConfpasswEdit); DDX Control(pDX, IDC EDIT2, m PasswordEdit); DDX Control(pDX, IDC EDIT1, m FilenameEdit); 161 DDX Text(pDX, IDC EDIT1, m Filename); DDX Text(pDX, IDC EDIT2, m Password); DDV MaxChars(pDX, m Password, 8); DDX Text(pDX, IDC EDIT3, m Confpassw); DDV MaxChars(pDX, m Confpassw, 8); //}}AFX DATA MAP } BEGIN MESSAGE MAP(CFileCodeDlg, CDialog) //{{AFX MSG MAP(CFileCodeDlg) //}}AFX MSG MAP END MESSAGE MAP() ///////////////////////////////////////////////////////////////////////////// // CFileCodeDlg message handlers void CFileCodeDlg::OnOK() { // TODO: Add extra validation here //return input CString temp1(""); CString temp2(""); GetDlgItemText(IDC EDIT1,temp1); for(int i=0; i<temp1.GetLength(); i++) pardlg->Fname[i]=temp1[i]; pardlg->Fname[i]=;

temp1=""; GetDlgItemText(IDC EDIT2,temp1); GetDlgItemText(IDC EDIT3,temp2); if (temp1.Compare(temp2)) { SetDlgItemText(IDC EDIT2,""); SetDlgItemText(IDC EDIT3,""); MessageBox("Confirmation doesnt match. Retype password", "Error",MB OK); return; } pardlg->CodeNum=temp1; CDialog::OnOK(); } 7.214 FileCodeDlgh A szükséges deklarációk elvégzése az osztály létrehozásához. #if !defined(AFX FILECODEDLG H E19C2661 475C 11D8 90AF 000AE642C6C5 INCLUDED ) #define AFX FILECODEDLG H E19C2661 475C 11D8 90AF 000AE642C6C5 INCLUDED #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 // FileCodeDlg.h : header file // #include "CardlistDlg.h" ///////////////////////////////////////////////////////////////////////////// // CFileCodeDlg dialog class CFileCodeDlg : public CDialog { // Construction public: CFileCodeDlg(CWnd* pParent = NULL); // standard constructor CCardlistDlg *pardlg; //parent dialog // Dialog Data

//{{AFX DATA(CFileCodeDlg) enum { IDD = IDD DIALOGFILECODE }; CEdit m ConfpasswEdit; CEdit m PasswordEdit; CEdit m FilenameEdit; CString m Filename; CString m Password; 162 CString m Confpassw; //}}AFX DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX VIRTUAL(CFileCodeDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX VIRTUAL // Implementation protected: // Generated message map functions //{{AFX MSG(CFileCodeDlg) virtual void OnOK(); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX FILECODEDLG H E19C2661 475C 11D8 90AF 000AE642C6C5 INCLUDED ) 7.215 Scardcpp Az alábbi fájl teljes mértékben azonos a GSView.exe forráskódjában szereplővel, hiszen pont ezért történt az érintett osztály létrehozása, hogy univerzális módon felhasználható legyen. Egyetlen kivétel

azért mégis van, a fájl első sorában az #include ”StdAfx.h” szerepel, nem pedig az Aladdin Free Public Licencre figyelmeztető kötelező fejléc 7.216 Scardh Az alábbi fájl szintén azonos a GSView.exe forráskódjában szereplővel, a fájl első sorában azonban #include <afxwinh> és a kötelező fejléc nem szerepel, ugyanis a Visual Studioban az előfordított header már tartalmazza a megfelelő „include”-okat. 7.217 res/Cardlistrc2 A manuálisan szerkeszthető erőforrásfájl automatikusan jön mindig létre. Jelenleg nem tartalmaz új komponenst. // // CARDLIST.RC2 - resources Microsoft Visual C++ does not edit directly // #ifdef APSTUDIO INVOKED #error this file is not editable by Microsoft Visual C++ #endif //APSTUDIO INVOKED ///////////////////////////////////////////////////////////////////////////// // Add manually edited resources here. ///////////////////////////////////////////////////////////////////////////// 163 7.218 Cardlistico A

program nagy (32x32 képpont) és kis méretű (16x16 képpont) ikonjait tartalmazza. A Visual Studio ikonszerkesztőjével hoztam létre. 164 8. A GSM SIM kártya karbantartására szolgáló VC6Sample magyar verziójú Visual C++ 6 nyelvű forráskódja A korábbi programok és forráskódok angol nyelvezetével ellentétben itt mind a szoftver, mind a forráskód magyar nyelvű, utóbbi esetben természetesen csak a komment sorok. Azért volt erre szükség, mert egyrészt ez már nem szerves része az Aladdin Ghostview-nak és nem köt a felhasználói szerződés, másrészt angol nyelven számtalan jó-rossz leírás található intelligenskártya és azon belül SIM kártya témában. Adott tehát a számtalan kiaknázatlan lehetőséggel bíró, eleddig validációra használt Scard osztály, szükségesnek éreztem legalább részben bemutatni a benne rejlő lehetőségeket. A program szintén egy dialógus alapú alkalmazás, melyet teljes egészében a Visual Studio

használatával hoztam létre. Fejlesztési lehetőség számos helyen lehetséges, például felhasználóbarát lehetőség, ha új SIM kártya vásárlásakor nem kellene minden régi számot egyesével átirogatni az új kártyára, hanem egyfajta „SIM Commander”-szerűen átmásolhatnánk őket. 8.1 A létrehozott fájlok (19 darab) - VC6Sample.dsw a workspace definíciós fájl (egyetlen projektet tartalmaz) - VC6Sample.dsp a VC6Sample nevű projekt definíciós fájlja - VC6Sample.cpp a tulajdonképpeni főprogram - VC6Sample.h a hozzá tartozó header fájl - VC6Sample.rc a főprogram erőforrás-definíciós fájlja - resource.h konstansdefiníciók az erőforrásokhoz - StdAfx.cpp a Visual Studio általános előfordított header fájlja - StdAfx.h a hozzá tartozó definíciós fájl - VC6SampleDlg.cpp a tulajdonképpeni fődialógus-ablak implementációja - VC6SampleDlg.h a fődialógus-ablak definíciós fájlja - EditDlg.cpp a módosításokra

használt dialógusablak implementációja - EditDlg.h a hozzá tartozó definíciós fájl - Scard.cpp az intelligenskártya-olvasását kezelő osztály megvalósítása - Scard.h az intelligenskártya-olvasását kezelő osztály definíciója - ReadMe.txt rövid leírás a programról angol nyelven - Olvass.el! rövid leírás a programról magyar nyelven - res/VC6Sample.rc2 manuálisan szerkeszthető erőforrás-definíció - res/VC6Sample.ico a program ikonja - Scard.err hibaüzenetek szövegét tartalmazó fájl Az említett állományok a VC6Sample alkönyvtárban találhatók a mellékelt adathordozón. 165 8.2 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 VC6Sample alkönyvtárban találhatók meg 8.21 VC6Sampledsw A Microsoft Visual C++ 6 által generált fájl, mely a projektek nevét tartalmazza, jelenleg

a VC6Sample nevű projektet. Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "VC6Sample"=".VC6Sampledsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### 8.22 VC6Sampledsp Szintén automatikusan generált fájl ez a projekt definíciós fájl. Tartalmaz minden a fordításhoz szükséges információt (nagyon hasonlóan egy makefile-hoz), a fájlok neveit, a megadott csoportosítási szempontokat stb. Jelenleg különösebb módosítások nélkül szerepel # Microsoft Developer Studio Project File - Name="VC6Sample" - Package Owner=<4> # Microsoft

Developer Studio Generated Build File, Format Version 6.00 # * DO NOT EDIT # TARGTYPE "Win32 (x86) Application" 0x0101 CFG=VC6Sample - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "VC6Sample.mak" !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "VC6Sample.mak" CFG="VC6Sample - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "VC6Sample - Win32 Release" (based on "Win32 (x86) Application") !MESSAGE "VC6Sample - Win32 Debug" (based on "Win32 (x86) Application") 166 !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc ProjName "" # PROP Scc LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF

"$(CFG)" == "VC6Sample - Win32 Release" # PROP BASE Use MFC 6 # PROP BASE Use Debug Libraries 0 # PROP BASE Output Dir "Release" # PROP BASE Intermediate Dir "Release" # PROP BASE Target Dir "" # PROP Use MFC 6 # PROP Use Debug Libraries 0 # PROP Output Dir "Release" # PROP Intermediate Dir "Release" # PROP Target Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D " WINDOWS" /D " AFXDLL" /Yu"stdafx.h" /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D " WINDOWS" /D " AFXDLL" /D " MBCS" /Yu"stdafx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" /d " AFXDLL" # ADD RSC /l 0x409 /d "NDEBUG" /d " AFXDLL"

BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 # ADD LINK32 /nologo /subsystem:windows /machine:I386 !ELSEIF "$(CFG)" == "VC6Sample - Win32 Debug" # PROP BASE Use MFC 6 # PROP BASE Use Debug Libraries 1 # PROP BASE Output Dir "Debug" # PROP BASE Intermediate Dir "Debug" # PROP BASE Target Dir "" # PROP Use MFC 5 # PROP Use Debug Libraries 1 # PROP Output Dir "Debug" # PROP Intermediate Dir "Debug" # PROP Target Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D " DEBUG" /D " WINDOWS" /D " AFXDLL" /Yu"stdafx.h" /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D " DEBUG" /D " WINDOWS" /D " MBCS" /Yu"stdafx.h" /FD /GZ /c # ADD BASE MTL /nologo /D " DEBUG" /mktyplib203 /win32 #

ADD MTL /nologo /D " DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d " DEBUG" /d " AFXDLL" # ADD RSC /l 0x409 /d " DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target # Name "VC6Sample - Win32 Release" # Name "VC6Sample - Win32 Debug" # Begin Group "Source Files" # PROP Default Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.EditDlgcpp # End Source File 167 # Begin Source File SOURCE=.Scardcpp # End Source File # Begin Source File SOURCE=.StdAfxcpp # ADD CPP /Yc"stdafx.h" # End Source File # Begin Source File SOURCE=.VC6Samplecpp # End Source File # Begin Source File SOURCE=.VC6Samplerc # End Source File # Begin Source File SOURCE=.VC6SampleDlgcpp # End

Source File # End Group # Begin Group "Header Files" # PROP Default Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.EditDlgh # End Source File # Begin Source File SOURCE=.Resourceh # End Source File # Begin Source File SOURCE=.Scardh # End Source File # Begin Source File SOURCE=.StdAfxh # End Source File # Begin Source File SOURCE=.VC6Sampleh # End Source File # Begin Source File SOURCE=.VC6SampleDlgh # End Source File # End Group # Begin Group "Resource Files" # PROP Default Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # Begin Source File SOURCE=. esVC6Sampleico # End Source File # Begin Source File SOURCE=. esVC6Samplerc2 # End Source File # End Group # Begin Source File SOURCE=.ReadMetxt # End Source File # End Target # End Project 8.23 VC6Samplecpp A megadott programozói szempontok alapján automatikusan generált fájl, a tulajdonképpeni főprogram. Nincs más feladata, mint elindítani CVC6SampleDlg osztály egy

példányát (dlg), és beállítani a megjelenítés tulajdonságait. 168 // VC6Sample.cpp : Defines the class behaviors for the application // #include "stdafx.h" #include "VC6Sample.h" #include "VC6SampleDlg.h" #ifdef DEBUG #define new DEBUG NEW #undef THIS FILE static char THIS FILE[] = FILE ; #endif ///////////////////////////////////////////////////////////////////////////// // CVC6SampleApp BEGIN MESSAGE MAP(CVC6SampleApp, CWinApp) //{{AFX MSG MAP(CVC6SampleApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX MSG ON COMMAND(ID HELP, CWinApp::OnHelp) END MESSAGE MAP() ///////////////////////////////////////////////////////////////////////////// // CVC6SampleApp construction CVC6SampleApp::CVC6SampleApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance }

///////////////////////////////////////////////////////////////////////////// // The one and only CVC6SampleApp object CVC6SampleApp theApp; ///////////////////////////////////////////////////////////////////////////// // CVC6SampleApp initialization BOOL CVC6SampleApp::InitInstance() { // 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(); #else Enable3dControlsStatic(); #endif // Call this when using MFC in a shared DLL // Call this when linking to MFC statically CVC6SampleDlg dlg; m pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed,

return FALSE so that we exit the // application, rather than start the applications message pump. return FALSE; } 169 8.24 VC6Sampleh Szintén automatikusan generált fájl, az előbbi header fájlja, mely a főprogram-osztály (CVC6SampleApp) osztály definícióját tartalmazza. // VC6Sample.h : main header file for the VC6SAMPLE application // #if !defined(AFX VC6SAMPLE H 384992C5 F8F8 11D3 B375 006008CD4928 INCLUDED ) #define AFX VC6SAMPLE H 384992C5 F8F8 11D3 B375 006008CD4928 INCLUDED #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 #ifndef AFXWIN H #error include stdafx.h before including this file for PCH #endif #include "resource.h" // main symbols ///////////////////////////////////////////////////////////////////////////// // CVC6SampleApp: // See VC6Sample.cpp for the implementation of this class // class CVC6SampleApp : public CWinApp { public: CVC6SampleApp(); // Overrides // ClassWizard generated virtual function overrides

//{{AFX VIRTUAL(CVC6SampleApp) public: virtual BOOL InitInstance(); //}}AFX VIRTUAL // Implementation //{{AFX MSG(CVC6SampleApp) // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX MSG DECLARE MESSAGE MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX VC6SAMPLE H 384992C5 F8F8 11D3 B375 006008CD4928 INCLUDED ) 8.25 VC6Samplerc A Visual Studio varázslója segítségével készített fájl. Két, viszonylag összetett dialógusablakot definiál A főablak a kártya tulajdonságai mellett egy listában jeleníti meg a lekért információkat. A szerkesztőablakban pedig a választott információk módosíthatók //Microsoft Developer Studio generated resource script. // #include "resource.h" #define

APSTUDIO READONLY SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. 170 // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO READONLY SYMBOLS ///////////////////////////////////////////////////////////////////////////// // Hungarian resources #if !defined(AFX RESOURCE DLL) || defined(AFX TARG HUN) #ifdef WIN32 LANGUAGE LANG HUNGARIAN, SUBLANG DEFAULT #pragma code page(1250) #endif // WIN32 ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD VC6SAMPLE DIALOG DIALOGEX 0, 0, 328, 193 STYLE DS MODALFRAME | DS 3DLOOK | WS POPUP | WS VISIBLE | WS CAPTION | WS SYSMENU EXSTYLE WS EX APPWINDOW CAPTION "SIM Példa" FONT 8, "MS Sans Serif" BEGIN PUSHBUTTON "Kilépés",IDCANCEL,264,172,50,14 PUSHBUTTON "Újraolvas",IDC REFRESH,214,172,50,14 CONTROL

"PIN1",IDC RADIOPIN1,"Button",BS AUTORADIOBUTTON | WS GROUP | WS TABSTOP,259,33,25,10 CONTROL "PIN2",IDC RADIOPIN2,"Button",BS AUTORADIOBUTTON,289,33, 25,10 EDITTEXT IDC PIN,208,43,50,14,ES PASSWORD | ES AUTOHSCROLL | ES NUMBER PUSHBUTTON "PIN ellenőrzés",IDC VERIFY,264,43,50,14 DEFPUSHBUTTON "Beolvas",IDREAD,215,113,50,14 LTEXT "PIN ellenőrzése",IDC STATIC,208,33,49,8 LTEXT "A helytelen kód tönkreteheti a kártyát!",IDC STATIC,202, 66,112,8 LTEXT "Sorszám:",IDC STATIC1,4,7,31,8 GROUPBOX "PIN 1 PIN 2 (lehetőség maradt)",IDC STATIC2,208,7,116, 23 LTEXT "Kártyatípus:",IDC STATIC4,4,21,37,8 CONTROL "PIN aktív",IDC CHECKPINAKTIV,"Button",BS AUTOCHECKBOX | WS TABSTOP,261,18,54,9 LTEXT "Figyelem!",IDC STATIC,219,58,31,8 COMBOBOX IDC COMBOTEMA,4,41,194,49,CBS DROPDOWNLIST | CBS SORT | WS VSCROLL | WS TABSTOP EDITTEXT IDC LIST,4,53,194,133,ES

MULTILINE | ES AUTOVSCROLL | ES AUTOHSCROLL | ES WANTRETURN | WS VSCROLL | WS HSCROLL PUSHBUTTON "Szerkeszt",IDC SZERKESZT,215,127,50,14 END IDD EDITDLG DIALOG DISCARDABLE 0, 0, 187, 112 STYLE DS MODALFRAME | WS POPUP | WS CAPTION | WS SYSMENU CAPTION "Szerkeszt" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "Vége",IDOK,132,43,50,14 EDITTEXT IDC SORSZAM,7,7,40,12,ES NUMBER CONTROL "Spin2",IDC SSZSCROLL,"msctls updown32",UDS SETBUDDYINT | UDS ALIGNRIGHT | UDS AUTOBUDDY | UDS ARROWKEYS,47,7,10, 12 PUSHBUTTON "Beolvas",IDC BEOLVAS,80,7,50,14 PUSHBUTTON "Elmentés",IDC KIIR,132,7,50,14 CONTROL "Törölt",IDC DELETED,"Button",BS AUTOCHECKBOX | WS TABSTOP,7,23,44,11 EDITTEXT IDC TSZAM,7,44,55,12 EDITTEXT IDC IDO,63,44,67,12 EDITTEXT IDC SZOVEGMEZO,7,57,175,48,ES MULTILINE | ES AUTOVSCROLL | ES WANTRETURN | WS VSCROLL LTEXT "Szám",IDC STATIC,7,34,51,8 LTEXT "Dátum",IDC

STATIC,63,34,62,8 END 171 ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD VC6SAMPLE DIALOG, DIALOG BEGIN LEFTMARGIN, 4 RIGHTMARGIN, 324 TOPMARGIN, 7 BOTTOMMARGIN, 186 END IDD EDITDLG, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 182 TOPMARGIN, 7 BOTTOMMARGIN, 105 END END #endif // APSTUDIO INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog Info // IDD VC6SAMPLE DIALOG DLGINIT BEGIN IDC COMBOTEMA, 0x403, 13, 0 0x6153, 0xe16a, 0x2074, 0x7a73, IDC COMBOTEMA, 0x403, 30, 0 0x4d53, 0x2053, 0x5228, 0x76f6, 0x2073, 0x7afc, 0x6e65, 0x7465, IDC COMBOTEMA, 0x403, 14, 0 0x6554, 0x656c, 0x6f66, 0x736e, 0 END 0x6de1, 0x6b6f, "00" 0x6469, 0x7320, 0xf67a, 0x6576, 0x6567, 0x6b65, 0x0029, 0xe17a, 0x6f6d, 0x006b, #endif // Hungarian resources /////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////// // English (U.S) resources #if !defined(AFX RESOURCE DLL) || defined(AFX TARG ENU) #ifdef WIN32 LANGUAGE LANG ENGLISH, SUBLANG ENGLISH US #pragma code page(1252) #endif // WIN32 #ifdef APSTUDIO INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h"" " "" END 3 TEXTINCLUDE DISCARDABLE BEGIN "#define AFX NO SPLITTER RESOURCES " 172 "#define AFX NO OLE RESOURCES " "#define AFX NO TRACKER RESOURCES " "#define AFX NO PROPERTY RESOURCES " " " "#if !defined(AFX RESOURCE DLL) || defined(AFX TARG ENU) " "#ifdef WIN32 " "LANGUAGE 9, 1 " "#pragma code page(1252) " "#endif // WIN32 " "#include

""res\VC6Sample.rc2"" // non-Microsoft Visual C++ edited resources " "#include ""afxres.rc"" // Standard components " "#endif " "" END #endif // APSTUDIO INVOKED ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDR MAINFRAME ICON DISCARDABLE "res\VC6Sample.ico" #ifndef MAC ///////////////////////////////////////////////////////////////////////////// // // Version // VS VERSION INFO VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL #ifdef DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "" VALUE "CompanyName", "" VALUE

"FileDescription", "VC6Sample MFC Application" VALUE "FileVersion", "1, 0, 0, 1" VALUE "InternalName", "VC6Sample" VALUE "LegalCopyright", "Copyright (C) 2000" VALUE "LegalTrademarks", "" VALUE "OriginalFilename", "VC6Sample.EXE" VALUE "PrivateBuild", "" VALUE "ProductName", "VC6Sample Application" VALUE "ProductVersion", "1, 0, 0, 1" VALUE "SpecialBuild", "" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #endif // ! MAC #endif // English (U.S) resources ///////////////////////////////////////////////////////////////////////////// 173 #ifndef APSTUDIO INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // #define AFX NO SPLITTER RESOURCES

#define AFX NO OLE RESOURCES #define AFX NO TRACKER RESOURCES #define AFX NO PROPERTY RESOURCES #if !defined(AFX RESOURCE DLL) || defined(AFX TARG ENU) #ifdef WIN32 LANGUAGE 9, 1 #pragma code page(1252) #endif // WIN32 #include "resVC6Sample.rc2" // non-Microsoft Visual C++ edited resources #include "afxres.rc" // Standard components #endif ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO INVOKED 8.26 resourceh A ClassWizard segítségével lett létrehozva ez a konstansdefiníciós fájl, mely a program által lekezelendő üzenetek azonosítóit és a dialógusablak-kontrollok azonosítóit tartalmazza. //{{NO DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by VC6Sample.rc // #define IDD VC6SAMPLE DIALOG 102 #define IDR MAINFRAME 128 #define IDD EDITDLG 130 #define IDREAD 1000 #define IDC RESET 1001 #define IDC VERIFY 1002 #define IDC PIN 1003 #define IDC STATIC2 1004 #define IDC

STATIC1 1005 #define IDC REFRESH 1007 #define IDC RADIOPIN1 1008 #define IDC RADIOPIN2 1010 #define IDC STATIC4 1014 #define IDC CHECKPINAKTIV 1015 #define IDC COMBOTEMA 1018 #define IDC LIST 1021 #define IDC SZERKESZT 1022 #define IDC SORSZAM 1023 #define IDC DELETED 1024 #define IDC TSZAM 1025 #define IDC SZOVEGMEZO 1026 #define IDC BEOLVAS 1027 #define IDC KIIR 1028 #define IDC IDO 1033 #define IDC SSZSCROLL 1035 // Next default values for new objects // #ifdef APSTUDIO INVOKED #ifndef APSTUDIO READONLY SYMBOLS #define APS NEXT RESOURCE VALUE #define APS NEXT COMMAND VALUE #define APS NEXT CONTROL VALUE #define APS NEXT SYMED VALUE #endif #endif 131 32771 1036 101 174 8.27 StdAfxcpp Az előfordított header fájl üres implementációja. Jelenleg használaton kívül van, a Visual Studio automatikusan hozta létre. Mindenképpen érdemes meghagyni, ha el akarjuk kerülni a projekt fájl kézzel történő módosítását, valamint minden temporáris fájl törlését, majd

az azt követő, igaz immár automatikus újralétrehozását. // stdafx.cpp : source file that includes just the standard includes // VC6Sample.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" 8.28 StdAfxh Az előbbi fájl header fájlja kiegészítve a magyarországi mobilszolgáltató cégek neveinek definiálásaként néhány define makróval. Ezekre ugyanis később szükség van a régebbi típusú SIM kártyák támogatásánál, amelyek még nem tartalmazzák a szolgáltató nevét a kártyán. // stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX STDAFX H 384992C9 F8F8 11D3 B375 006008CD4928 INCLUDED ) #define AFX STDAFX H 384992C9 F8F8 11D3 B375 006008CD4928 INCLUDED #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 #define VC EXTRALEAN // Exclude

rarely-used stuff from Windows headers #include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls #ifndef AFX NO AFXCMN SUPPORT #include <afxcmn.h> // MFC support for Windows Common Controls #endif // AFX NO AFXCMN SUPPORT //Szolgaltatok #define HUPANNONGSMID "893620" #define HUPANNONGSM "Pannon GSM" #define HUWESTEL900ID "893630" #define HUWESTEL900 "Westel 900" #define HUVODAFONEID "893670" #define HUVODAFONE "Vodafone" //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX STDAFX H 384992C9 F8F8 11D3 B375 006008CD4928 INCLUDED ) 8.29 VC6SampleDlgcpp Az alábbi 28 oldalnyi (55 kilobájtnyi) forráskód a fő dialógusablak(osztály) implementációja. Igen összetett lévén, függvényenkénti

magyarázatra szorul Számtalan függvényei közül az első négy globális függvény. Nem szigorúan az osztályhoz kötődő műveleteket végeznek, hanem karakterkonverziókat A char GSMabc(int betu) visszatérési értékként a megadott ETSI 3.38 által definiált karakternek a magyar ASCII karakterkészletnek megfelelő értékével tér vissza. A char ReGSMabc(int betu) ennek éppen az ellenkezőjét végzi, ETSI-vé konvertál. A DekodAlfanum(char 175 *be, int bepoint, int becount, char ki) függvény a 7 bites alfanumeri- kus karaktersorozatokat konvertálja 8 bitessé (a nyolcadik bit 0 lesz), míg az Alfanum(char *ki, int kipoint, char be) ennek ellenkezőjét végzi. A konstruktor a változók kezdeti értékeinek megadására szolgál. Az utána következő DoDataExchange(CDataExchange* pDX) azonban egy saját üzenetkezelőt is tartalmaz az eddig megszokottal ellentétben. Ennek az a célja, hogy az ScardServer felől jövő üzeneteket is feldolgozhassuk, s így

új kártya behelyezése esetén automatikusan frissülnek a képernyőn lévő kártyaadatok. Az OnPaint() a kirajzolásért felel. Ezen kívül, ha nem áll rendelkezésre a megfelelő kártyakibocsátóról szóló információ, a sorozatszám első hat jegye alapján állapítja meg azt. Az OnVerify() a „PIN kód ellenőrzése” gomb esetén hívódik meg, gyakorlatilag az Editboxból kiolvasott paraméterrel hívja meg a card.VerifyPin CScard osztálybeli függvényt. A GetSIMProvider(char *prname) próbálja az OnPaint() hívására a „6f46” nevű SIM kártyabeli fájlból kideríteni a kártya kibocsátóját. A CheckSIM() függvény a GSM könyvtár (7f20) kiválasztásával igyekszik megbizonyosodni arról, hogy SIM kártya van-e az olvasóban. Ez egy széles körben alkalmazott ellenőrzési eljárás, ugyanis az azonosító a SIM kártyaként használható kártyák számára van fenntartva. A GetSIMSerial() a SIM kártya állapotáról kér információt

(card.GetMessage) Az eljárás tulajdonképpen az aktuálisan kiválasztott fájlról ad elsősorban információt, de emellett azokat a kártyaparamétereket is megadja, amelyeket egyébként az ETSI szerint definiált, de a CScard osztályban általam feleslegesnek véltként nem implementált, Status (ETSI 11.11 4316) függvényhívás ad vissza Az OnRefresh() az „Újraolvas” gomb lenyomásakor vagy új kártya behelyezésekor lefutó függvény, mely az előző két függvényt használva, ha SIM kártyát talál az olvasóban, akkor kiolvassa annak adatait. Az OnRadiopin kezdetű függvények által választhatjuk ki az elsődleges vagy másodlagos PIN kódot, az OnCheckpinaktiv() által ki-be kapcsolhatjuk a PIN kódot (csak az elsődleges PIN kód kapcsolható ki), a Waiting(int state) akkor hívódik meg, ha hosszú ideig tartó olvasás van folyamatban, addig letiltja az inputkezelést, az OnStatusChanged(WPARAM wParam, LPARAM lParam) a már említett ScardServer által

küldendő üzenetekre reagál. Az OnRead() függvény a kiválasztott típusnak megfelelően az SMS-ek, Telefonszámok, vagy a Saját számok rekordokat listázza a képernyőre. Az OnSzerkeszt() új dialógusablakot hoz létre, melyben módosíthatjuk a rekordok tartalmát, ezt kiszolgáló függvények a Beolvas(int ssz, int &del, char *szam, char ido, char *text) és a Kiir(int ssz, int del, char szam, char ido, char *text). Ezek csak egyetlen rekordot olvasnak be, vagy írnak ki Nyilvános függvények, mivel a EditDlgcpp-ből hívjuk meg őket // VC6SampleDlg.cpp : implementation file // #include "stdafx.h" #include "VC6Sample.h" 176 #include "VC6SampleDlg.h" #include "SCard.h" #include "EditDlg.h" #ifdef DEBUG #define new DEBUG NEW #undef THIS FILE static char THIS FILE[] = FILE ; #endif ///////////////////////////////////////////////////////////////////////////// // Common functions enum {PIN 1, PIN 2}; //Melyik

PIN kodot valasztjuk char GSMabc(int betu) { //Atkonvertalja a karakterkeszletet magyarra betu=((unsigned char)betu); char ret; if (0xff==betu) return (ret= ); //Az 0xff karakter nem resze az ABC-nek! if (0x00==betu) return (ret=@); if (0x01==betu) return (ret=Ł); if (0x02==betu) return (ret=$); if (0x03==betu) return (ret=Y); if (0x04==betu) return (ret=é); if (0x05==betu) return (ret=é); if (0x06==betu) return (ret=ú); if (0x07==betu) return (ret=í); if (0x08==betu) return (ret=ó); if (0x09==betu) return (ret=ç); if (0x0a==betu) return (ret=betu); if (0x0b==betu) return (ret=O); if (0x0c==betu) return (ret=o); if (0x0d==betu) return (ret=betu); if (0x0e==betu) return (ret=Á); if (0x0f==betu) return (ret=á); if (0x10==betu) return (ret=betu); (nincs) if (0x11==betu) return (ret= ); if (0x12==betu) return (ret=betu); (nincs) if (0x13==betu) return (ret=betu); (nincs) if (0x14==betu) return (ret=betu); (nincs) if (0x15==betu) return (ret=betu); (nincs) if (0x16==betu) return

(ret=betu); (nincs) if (0x17==betu) return (ret=betu); (nincs) if (0x18==betu) return (ret=betu); (nincs) if (0x19==betu) return (ret=betu); (nincs) if (0x1a==betu) return (ret=betu); (nincs) if (0x1b==betu) return (ret= ); szekvencia if (0x1c==betu) return (ret=betu); if (0x1d==betu) return (ret=betu); if (0x1e==betu) return (ret=ß); if (0x1f==betu) return (ret=É); if (( <=betu)&&(betu<=#)) return (ret=betu); if (0x24==betu) return (ret=¤); if ((%<=betu)&&(betu<=&)) return (ret=betu); if (0x27==betu) return (ret=0x60); if (((<=betu)&&(betu<=?)) return (ret=betu); if (0x40==betu) return (ret=betu); felkialtojel if ((A<=betu)&&(betu<=Z)) return (ret=betu); if (0x5b==betu) return (ret=Ä); if (0x5c==betu) return (ret=Ö); if (0x5d==betu) return (ret=Ń); if (0x5e==betu) return (ret=Ü); 177 //ff ures //00 //01 //02 //03 //04 //05 //06 //07 //08 //09 //0a //0b //0c //0d //0e //0f //10 libra dollar yen LF Oathuzva oathuzva

CR Delta //11 //12 Fi //13 Gamma //14 Lambda //15 Omega //16 Pi //17 Pszi //18 Szigma //19 Omega //1a Khi //1b Escape //1c AE //1d ae //1e //1f //20-23 //24 //25-26 //27 //28-3f //40 forditott //41-5a //5b //5c //5d Nhullam //5e if (0x5f==betu) return (ret=§); paragrafus if (0x60==betu) return (ret=betu); kerdojel if ((a<=betu)&&(betu<=z)) return (ret=betu); if (0x7b==betu) return (ret=ä); if (0x7c==betu) return (ret=ö); if (0x7d==betu) return (ret=ň); if (0x7e==betu) return (ret=ü); if (0x7f==betu) return (ret=á); //5f //60 forditott //61-7a //7b //7c //7d nhullam //7e //7f return (ret=betu); } char ReGSMabc(char betu) {//Atkonvertalja a karakterkeszletet GSM-re betu=((unsigned char)betu); char ret; if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if if (@==betu) return (ret=0x00); (Ł==betu) return (ret=0x01); ($==betu) return (ret=0x02); (Y==betu) return

(ret=0x03); (é==betu) return (ret=0x04); (é==betu) return (ret=0x05); (ú==betu) return (ret=0x06); (í==betu) return (ret=0x07); (ó==betu) return (ret=0x08); (ç==betu) return (ret=0x09); (0x0a==betu) return (ret=betu); (0x0b==betu) return (ret=betu); (0x0c==betu) return (ret=betu); (0x0d==betu) return (ret=betu); (Á==betu) return (ret=0x0e); (á==betu) return (ret=0x0f); (0x10==betu) return (ret=betu); ( ==betu) return (ret=0x11); (0x12==betu) return (ret=betu); (0x13==betu) return (ret=betu); (0x14==betu) return (ret=betu); (0x15==betu) return (ret=betu); (0x16==betu) return (ret=betu); (0x17==betu) return (ret=betu); (0x18==betu) return (ret=betu); (0x19==betu) return (ret=betu); (0x1a==betu) return (ret=betu); (0x1b==betu) return (ret=betu); (0x1c==betu) return (ret=betu); (0x1d==betu) return (ret=betu); (ß==betu) return (ret=0x1e); (É==betu) return (ret=0x1f); (( <=betu)&&(betu<=#)) return (¤==betu) return (ret=0x24); ((%<=betu)&&(betu<=&))

return (0x60==betu) return (ret=0x27); (((<=betu)&&(betu<=?)) return (0x40==betu) return (ret=betu); ((A<=betu)&&(betu<=Z)) return (Ä==betu) return (ret=0x5b); (Ö==betu) return (ret=0x5c); (Ń==betu) return (ret=0x5d); (Ü==betu) return (ret=0x5e); (§==betu) return (ret=0x5f); ((a<=betu)&&(betu<=z)) return (ä==betu) return (ret=0x7b); (ö==betu) return (ret=0x7c); (ň==betu) return (ret=0x7d); (ü==betu) return (ret=0x7e); (á==betu) return (ret=0x7f); //00 //01 libra //02 dollar (ret=betu); (ret=betu); (ret=betu); (ret=betu); (ret=betu); //03 yen //04 //05 //06 //07 //08 //09 //0a LF //0b Oathuzva //0c oathuzva //0d CR //0e //0f //10 Delta (nincs) //11 //12 Fi (nincs) //13 Gamma (nincs) //14 Lambda (nincs) //15 Omega (nincs) //16 Pi (nincs) //17 Pszi (nincs) //18 Szigma (nincs) //19 Omega (nincs) //1a Khi (nincs) //1b Escape szekvencia //1c AE //1d ae //1e //1f //20-23 //24 //25-26 //27 //28-3f //40 forditott felkialtojel //41-5a //5b

//5c //5d Nhullam //5e //5f paragrafus //61-7a //7b //7c //7d nhullam //7e //7f return (ret=betu); } //parameterek: //bejovo karaktersorozat, pointer a feldolgozando resz elejere //vart karakterek szama, kimeno karaktersorozat 178 void DekodAlfanum(char *be, int bepoint, int becount, char ki) { char betu[2]; char tmp; int kicount=0; int i; int k=bepoint; int bitc=0; //bitszamlalo int bi; //belso ciklus int bitmaszk[8]; //bitmaszkok elkeszitese bitmaszk[0]=1; //2 hatvanyai for (i=1; i<8; i++) { bitmaszk[i]=bitmaszk[i-1]*2; } tmp=be[k]; for (i=0; i<becount; i++) {//7 bites szamjegyek betu[0]=; for (bi=0; bi<7; bi++) {//egy bit // 0 vagy 1 * 2^bi betu[0]+=((unsigned char)tmp%2)*bitmaszk[bi]; bitc++; //egy helyiertekkel jobbra tmp=(unsigned char)tmp/2; if (bitc>7) //kovetkezo karakter { bitc=0; k++; tmp=be[k]; } } //megvan egy betu ki[kicount++]=GSMabc(betu[0]); } } //parameterek: //kimeno karaktersorozat, pointer honnan kezdje irni //bejovo karaktersorozat void

Alfanum(char *ki, int kipoint, char be) { char betu[2]; char tmp; int becount=0; //kodolando szoveg pointere int i; //ciklusvaltozo int k=kipoint; //kodolt szoveg pointere int bitc=0; //bitszamlalo (a kodolt szovegen belul) int bi; //belso ciklus v. int bitmaszk[8]; //bitmaszkok elkeszitese bitmaszk[0]=1; //2 hatvanyai for (i=1; i<8; i++) { bitmaszk[i]=bitmaszk[i-1]*2; } tmp=ReGSMabc(be[becount]); betu[0]=; //a bejovo szoveg -val er veget! for (i=0; be[i]!=; i++) {//7 bites szamjegyek for (bi=0; bi<7; bi++) {//egy bit // 0 vagy 1 * 2^bi betu[0]+=((unsigned char)tmp%2)*bitmaszk[bitc]; bitc++; //egy helyiertekkel jobbra tmp=(unsigned char)tmp/2; if (bitc>7) //kovetkezo karakter { ki[k++]=betu[0]; bitc=0; 179 betu[0]=; } } //megvan egy kodolando betu tmp=ReGSMabc(be[++becount]); } ki[k++]=betu[0]; } ///////////////////////////////////////////////////////////////////////////// // CVC6SampleDlg dialog CVC6SampleDlg::CVC6SampleDlg(CWnd* pParent /=NULL/) :

CDialog(CVC6SampleDlg::IDD, pParent) { //Konstruktor //{{AFX DATA INIT(CVC6SampleDlg) m pin = T(""); m Psorszam = -1; m Pinactive = FALSE; m Eredmeny = T(""); //}}AFX DATA INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m hIcon = AfxGetApp()->LoadIcon(IDR MAINFRAME); serial=""; statussize=0; m Psorszam=PIN 1; Pin1maradt=Pin2maradt=0; waitstate=0; } void CVC6SampleDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX DATA MAP(CVC6SampleDlg) DDX Control(pDX, IDC LIST, m ListEdit); DDX Control(pDX, IDC COMBOTEMA, m TemaEdit); DDX Control(pDX, IDC CHECKPINAKTIV, m SetChkPin); DDX Control(pDX, IDC PIN, m pinEdit); DDX Text(pDX, IDC PIN, m pin); DDV MaxChars(pDX, m pin, 8); DDX Radio(pDX, IDC RADIOPIN1, m Psorszam); DDX Check(pDX, IDC CHECKPINAKTIV, m Pinactive); DDX LBString(pDX, IDC LIST, m Eredmeny); //}}AFX DATA MAP } //Uzenetkezelo fuggvenyek, kiegeszitve egy sajattal: (OnStatusChanged) BEGIN

MESSAGE MAP(CVC6SampleDlg, CDialog) //{{AFX MSG MAP(CVC6SampleDlg) ON WM PAINT() ON WM QUERYDRAGICON() ON BN CLICKED(IDREAD, OnRead) ON BN CLICKED(IDC VERIFY, OnVerify) ON BN CLICKED(IDC REFRESH, OnRefresh) ON BN CLICKED(IDC RADIOPIN1, OnRadiopin1) ON BN CLICKED(IDC RADIOPIN2, OnRadiopin2) ON BN CLICKED(IDC CHECKPINAKTIV, OnCheckpinaktiv) ON BN CLICKED(IDC SZERKESZT, OnSzerkeszt) //}}AFX MSG MAP ON MESSAGE(WM APP, OnStatusChanged) END MESSAGE MAP() ///////////////////////////////////////////////////////////////////////////// // CVC6SampleDlg message handlers BOOL CVC6SampleDlg::OnInitDialog() { //Inicializalas, egyszer fut le a legelejen CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the applications main window is not a dialog SetIcon(m hIcon, TRUE); // Set big icon SetIcon(m hIcon, FALSE); // Set small icon 180 // TODO: Add extra initialization here m pinEdit.LimitText(8); m TemaEdit.SetCurSel(0); //Inicializalas Error

myError=card.Init(); if(myError) { MessageBox("Nem található kártyaolvasó!","Hiba",MB OK); } //Regisztralas, hogy megerkezzenek az uzenetek az olvasorol char strcmd[255]; sprintf(strcmd,"System,AddHWndMsg,%ld,%ld",m hWnd,(DWORD)WM APP); if(myError=card.Comand(strcmd,0,NULL,0,NULL,0)) { MessageBox("A kártya nem olvasható!","Hiba",MB OK); } return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CVC6SampleDlg::OnPaint() { //Kirajzolas CPaintDC dc(this); // device context for painting if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM CXICON); int cyIcon =

GetSystemMetrics(SM CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m hIcon); } else { //Ha lathato az ablak if (serial.IsEmpty()) //ki kell olvasni { OnRefresh(); } //Sorszam RECT m RectSerial; GetDlgItem(IDC STATIC1)->GetWindowRect(&m RectSerial); ScreenToClient(&m RectSerial); int x=m RectSerial.right; int y=m RectSerial.top; dc.SetTextAlign(TA LEFT); dc.SelectStockObject(BLACK PEN); dc.SetBkMode(TRANSPARENT); dc.TextOut(x, y, serial); //Tipus RECT m RectType; GetDlgItem(IDC STATIC4)->GetWindowRect(&m RectType); ScreenToClient(&m RectType); x=m RectType.right; y=m RectType.top; dc.SetTextAlign(TA LEFT); dc.SelectStockObject(BLACK PEN); dc.SetBkMode(TRANSPARENT); CString Type(""); if (("-"!=serial)&&("?"!=serial)) { 181 char prname[30]; if (!GetSIMProvider(prname)) //implementalt a szolgaltatonev {

Type+=" "; int i=0; while (prname[i]) { Type+=prname[i++]; } } else {//ha nincs implementalva, akkor kiolvassuk a tablazatbol Type=serial.Mid(0, 4)+serialMid(5, 2); if (HUPANNONGSMID==Type) { Type+=" "; Type+=HUPANNONGSM; } else if (HUWESTEL900ID==Type) { Type+=" "; Type+=HUWESTEL900; } else if (HUVODAFONEID==Type) { Type+=" "; Type+=HUVODAFONE; } } } dc.TextOut(x, y, Type); //Pinszamlalo RECT m RectPincount; GetDlgItem(IDC STATIC2)->GetWindowRect(&m RectPincount); ScreenToClient(&m RectPincount); x=m RectPincount.left+20; y=(m RectPincount.top+m RectPincountbottom)/2; dc.SetTextAlign(TA LEFT); dc.SelectStockObject(BLACK PEN); dc.SetBkMode(TRANSPARENT); char tmp[1]; if (Pin1maradt>-1) sprintf(tmp, "%d", Pin1maradt); else sprintf(tmp, " "); dc.TextOut(x, y, tmp); x+=40; if (Pin2maradt>-1) sprintf(tmp, "%d", Pin2maradt); else sprintf(tmp, " "); dc.TextOut(x, y, tmp); //Pin aktiv-e m

SetChkPin.SetCheck(m Pinactive); //Eredmeny kijelzese CFont *PtrOldFont; CFont TempFont; //korabbi fontkeszlet elmentese //uj fontkeszlet "fix" TempFont.CreateStockObject(SYSTEM FIXED FONT); PtrOldFont=dc.SelectObject(&TempFont); m ListEdit.SetFont(&TempFont); SetDlgItemText(IDC LIST, m Eredmeny); dc.SelectObject(PtrOldFont); CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CVC6SampleDlg::OnQueryDragIcon() { return (HCURSOR) m hIcon; } 182 // Uzenetkezelo fuggvenyek //----------------------------------------------------------------------------------void CVC6SampleDlg::OnVerify() {//PIN kod ellenorzese int i; char Status[2]; Error myError; char Temppin[8]; char Pinerr[32]; //kell hozza a kod (min. 4 hossz) if (4 > GetDlgItemText(IDC PIN, Temppin, 8)) return; for(i=strlen(Temppin); i<8; i++) Temppin[i]=0xff; //ellenorzes if(myError=card.VerifyPin(m Psorszam+1, Temppin,

Status, sizeof(Status))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return; } if ((0x90==(unsigned char)Status[0])&&(0x00==(unsigned char)Status[1])) sprintf(Pinerr, "PIN kód rendben"); else if ((0x98==(unsigned char)Status[0])&&(0x08==(unsigned char)Status[1])) sprintf(Pinerr, "PIN kód nem elérhető"); else sprintf(Pinerr, "Hibás PIN kód!"); MessageBox(Pinerr,"PIN ellenőrzés",MB OK); OnRefresh(); } int CVC6SampleDlg::GetSIMProvider(char *prname) {//kiolvassa a 6f46 file tartalmat (ha letezik) int i; int meret; Error myError; char DataOut[32] = {0}; char FileID[2]={0x7f,0x20}; //Select directory GSM prname[0]=; //A GSM konyvtar kivalasztasa (7f20) if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van

MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } FileID[0]=0x6f; FileID[1]=0x46; //SPN file kivalasztasa if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor nem implementalt! return -1; } //Hossz ellenorzes (szabvany: 0x11) if(myError=card.GetMessage(statussize, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x67==(unsigned char)DataOut[0]) { //elter a hossz! a helyes hossz a [1] helyen if (myError=card.GetMessage((unsigned char)DataOut[1], DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } } meret=(unsigned char)DataOut[5]; 183 //A file "binaris" formatumu, kiolvassuk if(myError=card.ReadBinary(meret, DataOut, sizeof(DataOut))){

MessageBox("A kártya nem olvasható!", "Error", MB OK); return -1; } if ((0x90!=(unsigned char)DataOut[0])||(0x00!=(unsigned char)DataOut[1])) { MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //megvan for (i=3; ((0xff!=(unsigned char)DataOut[i])&&(i<meret+2)); i++) { prname[i-3]=(unsigned char)DataOut[i]; } prname[i-3]=; return 0; } int CVC6SampleDlg::CheckSIM() {//Ervenyes SIM kartya van-e az olvasoban char DataOut[32]={0}; char FileID[2]={0x7f,0x20}; Error myError; int retval=0; //Select directory GSM //Ha a GSM konyvtar elerheto, akkor ez SIM kartya (7f20) if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ return 0; } if (0x9f==(unsigned char)DataOut[0]) { retval=1; //ha rendben, akkor az allando statuszhossz megvan (neha megsem allando) statussize=(unsigned char)DataOut[1]; } return retval; } void CVC6SampleDlg::GetSIMSerial() {//Informacio kiolvasasa a kartyarol (sorszam, pinstatusz stb.) int i; char

DataOut[12]={0}; char FileID[2]={0x3f,0x00}; //Select MasterFile Error myError; char Statuserr[32]={0}; //Kivalasztjuk a gyokerkonyvtart if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return; } //Beolvassuk a konyvtar informaciokat if (myError=card.GetMessage(statussize, Statuserr, sizeof(Statuserr))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return; } if (0x67==(unsigned char)Statuserr[0]) { //elter a hossz! a helyes hossz a [1] helyen if (myError=card.GetMessage((unsigned char)Statuserr[1], Statuserr, sizeof(Statuserr))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return; } } if ((0x90!=(unsigned char)Statuserr[0])||(0x00!=(unsigned char)Statuserr[1])) { //Ha nem lehet

beolvasni, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); 184 return; } Pin1maradt=((unsigned char)Statuserr[20]%16); Pin2maradt=((unsigned char)Statuserr[22]%16); m Pinactive=!(((unsigned char)Statuserr[15]&0x80)); //Select ICC-ID FileID[0]=0x2f; FileID[1]=0xe2; //Kivalasztjuk a szeriaszamot tartalmazo filet if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return; } if (0x9f!=(unsigned char)DataOut[0]) { MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return; } //A file "binaris" formatumu, kiolvassuk if(myError=card.ReadBinary(10, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Error", MB OK); return; } if ((0x90!=(unsigned char)DataOut[0])||(0x00!=(unsigned char)DataOut[1])) { MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return; } //megvan az ertek

serial=""; char tag[1]; for(i=0; i<10; i+=2) { //fel vannak cserelve a szamjegyek! sprintf(tag, "%x",((unsigned char) DataOut[2+i])%16); serial+=tag; sprintf(tag, "%x",((unsigned char) DataOut[2+i])/16); serial+=tag; sprintf(tag, "%x",((unsigned char) DataOut[3+i])%16); serial+=tag; sprintf(tag, "%x",((unsigned char) DataOut[3+i])/16); serial+=tag; serial+=" "; } //Kiiras jon } void CVC6SampleDlg::OnRefresh() {// Frissitjuk a kartyarol rendelkezo informacioinkat if ("?"==serial) return; //ne hivodjon meg egyszerre ketszer serial="?"; statussize=0; Pin1maradt=Pin2maradt=-1; m Pinactive=FALSE; Invalidate(); UpdateWindow(); if(CheckSIM()) GetSIMSerial(); // kiolvassa a kartyaadatokat else { MessageBox("Érvénytelen SIM kártya!", "Hiba", MB OK); serial="-"; } Invalidate(); UpdateWindow(); } void CVC6SampleDlg::OnRadiopin1() { // Ha a PIN1 van kivalasztva if

(IsDlgButtonChecked(IDC RADIOPIN1)) { m Psorszam=PIN 1; } } 185 void CVC6SampleDlg::OnRadiopin2() { // Ha a PIN2 van kivalasztva if (IsDlgButtonChecked(IDC RADIOPIN2)) { m Psorszam=PIN 2; } } void CVC6SampleDlg::OnCheckpinaktiv() {//A PIN kod be/kikapcsolasa m Pinactive=!m Pinactive; m SetChkPin.EnableWindow(FALSE); //letiltjuk amig feldolgozzuk int i; char Status[2]; Error myError; char Temppin[8]; char Pinerr[32]; //kell hozza a kod (min. 4 hossz) if (4 > GetDlgItemText(IDC PIN, Temppin, 8)) { m SetChkPin.EnableWindow(TRUE); //vissza OnRefresh(); return; } for(i=strlen(Temppin); i<8; i++) Temppin[i]=0xff; //Beallitjuk a kivant statuszt if(myError=card.SetPinStatus(m Pinactive, Temppin, Status, sizeof(Status))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return; } if ((0x90==(unsigned char)Status[0])&&(0x00==(unsigned char)Status[1])) sprintf(Pinerr, "PIN kód rendben A PIN állapota megváltozott"); else sprintf(Pinerr,

"Hibás PIN kód!"); MessageBox(Pinerr,"PIN ellenőrzés",MB OK); m SetChkPin.EnableWindow(TRUE); OnRefresh(); //ujra elerheto az ablakelem } void CVC6SampleDlg::Waiting(int state) {//Varunk valamilyen esemenyre if (1==state) //enable { BeginWaitCursor(); waitstate=1; EnableWindow(FALSE); } else if (0==state) //disable { EndWaitCursor(); waitstate=0; EnableWindow(TRUE); } } LRESULT CVC6SampleDlg::OnStatusChanged(WPARAM wParam, LPARAM lParam) { // Kartyaolvasostatusz megvaltozott switch (wParam) { case 150: //Aktivva valt OnRefresh(); break; case 110: //Nincs kartya serial="-"; Invalidate(); UpdateWindow(); } return 0; } void CVC6SampleDlg::OnRead() 186 {//Kiolvassa az aktualis tartalmat Waiting(1); //hosszura nyulhat a beolvasas int i,j,k; int Rekordmeret, Rekorddb; Error myError; CString cardBytes(""); char DataOut[255] = {0}; int Temakor; char FileID[2]={0x7f,0x10}; //Select directory TELECOM //Uresre allitjuk a listat m

Eredmeny=""; // Milyen temakor van kivalasztva Temakor=m TemaEdit.GetCurSel(); m TemaEdit.GetLBText(Temakor, cardBytes); //A TELECOM konyvtar kivalasztasa (7f10) if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); Waiting(0); return; } //Minden file "rekord" formatumu bejegyzeseket tartalmaz //SMS if ("SMS (Rövid szöveges üzenetek)"==cardBytes) { FileID[0]=0x6f; FileID[1]=0x3c; //SMS file kivalasztasa if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba",

MB OK); Waiting(0); return; } //Hossz ellenorzes (szabvany: 0xb0) if(myError=card.GetMessage(statussize, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } if (0x67==(unsigned char)DataOut[0]) { //elter a hossz! a helyes hossz a [1] helyen if (myError=card.GetMessage((unsigned char)DataOut[1], DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } } //rekordmeret Rekordmeret=(unsigned char)DataOut[16]; //foglalt osszes meret Rekorddb=(unsigned char)DataOut[5]+((unsigned char)DataOut[4])*256; if (0x00==Rekordmeret) { //Ha nulla, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); Waiting(0); return; } //darabszam Rekorddb/=Rekordmeret; CString smselem(""); 187 char betu[2]; for (j=0; j<Rekorddb; j++) //Altalaban 15 SMS van { //1 rekord beolvasasa if (myError=card.ReadRecord((char)j+1, 0x04,

Rekordmeret, DataOut, sizeof(DataOut))) { MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } if ((0x98==(unsigned char)DataOut[0])&&(0x04==(unsigned char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ehhez a művelethez előbb fel kell oldani a PIN kódot!", "Hiba", MB OK); Waiting(0); return; } //feldolgozas k=2; //sorszam sprintf(betu, "%03d", j+1); smselem+=betu; smselem+=". "; //tipus int typ; switch ((unsigned char)DataOut[k++]) { case 0: smselem+="Törölt üzenet"; typ=0; break; case 1: smselem+="Olvasott üzenet"; typ=1; break; case 3: smselem+="Új üzenet"; typ=3; break; case 5: smselem+="Elküldött üzenet"; typ=5; break; case 7: smselem+="Tárolt üzenet"; typ=7; break; } smselem+=": "; if (typ==0) //Torolt uzenet {//megprobaljuk visszaallitani if ((0x00==(unsigned

char)DataOut[k])&&(0x00==(unsigned char)DataOut[k+3])) //Tarolt uzenet volt {//Service Centre:0 Length of Address: 0 typ=7; smselem+="(Tárolt üzenet) "; } else if ((0x00!=(unsigned char)DataOut[k])&&(0xff!=(unsigned char)DataOut[k])) //Olvasott uzenet volt {//Service Centre: nem 0 es nem ervenytelen (ff) typ=1; smselem+="(Olvasott üzenet) "; } } //ha ertelmes az uzenet if ((typ==1)||(typ==3)) { //Service Center int skipc=(unsigned char)DataOut[k++]; k+=skipc; 188 // TP-MTI k++; //kuldo // international format national format char)DataOut[k+1])) if ((0x91==(unsigned char)DataOut[k+1])||(0xa1==(unsigned //normal BCD { for(i=k+2; i<k+2+((unsigned char)DataOut[k]+1)/2; i++) {//fel vannak cserelve a szamjegyek betu[0]=((unsigned char)DataOut[i])%16; if (0x0f!=betu[0]) { betu[0]+=0x30; smselem+=betu[0]; } betu[0]=((unsigned char)DataOut[i])/16; if (0x0f!=betu[0]) { betu[0]+=0x30; smselem+=betu[0]; } } } else if (0xd0==(unsigned

char)DataOut[k+1]) //alfanumerikus { char cim[20]; int cimhossz=((unsigned char)DataOut[k]*4)/7; DekodAlfanum(DataOut, k+2, cimhossz, cim); for (i=0; i<cimhossz; i++) smselem+=cim[i]; } else { //nem tamogatott formatumu cim smselem+="Nem támogatott cím"; } k+=2+((unsigned char)DataOut[k]+1)/2; //szamok atugrasa smselem+="->"; //TP-PID k++; //date coding scheme: alfanumerikus if ((0==((unsigned char)DataOut[k]&0xcc))||(0xf0==((unsigned char)DataOut[k]&0xf4))) { k++; //Time-stamp smselem+="["; //ev betu[0]=0x30+((unsigned char)DataOut[k])%16; smselem+=betu[0]; betu[0]=0x30+((unsigned char)DataOut[k++])/16; smselem+=betu[0]; smselem+="."; //honap betu[0]=0x30+((unsigned char)DataOut[k])%16; smselem+=betu[0]; betu[0]=0x30+((unsigned char)DataOut[k++])/16; smselem+=betu[0]; smselem+="."; //nap betu[0]=0x30+((unsigned char)DataOut[k])%16; smselem+=betu[0]; betu[0]=0x30+((unsigned char)DataOut[k++])/16; smselem+=betu[0];

smselem+="."; //ora 189 betu[0]=0x30+((unsigned char)DataOut[k])%16; smselem+=betu[0]; betu[0]=0x30+((unsigned char)DataOut[k++])/16; smselem+=betu[0]; smselem+=":"; //perc betu[0]=0x30+((unsigned char)DataOut[k])%16; smselem+=betu[0]; betu[0]=0x30+((unsigned char)DataOut[k++])/16; smselem+=betu[0]; smselem+=":"; //masodperc betu[0]=0x30+((unsigned char)DataOut[k])%16; smselem+=betu[0]; betu[0]=0x30+((unsigned char)DataOut[k++])/16; smselem+=betu[0]; smselem+="] "; k++; //idozona char dekodoltszoveg[255]; int hossz=(unsigned char)DataOut[k]; DekodAlfanum(DataOut, k+1, hossz, dekodoltszoveg); for (i=0; i<hossz; i++) { if ((dekodoltszoveg[i]!=0x0a)&&(dekodoltszoveg[i]!=0x0d)) { smselem+=dekodoltszoveg[i]; } else { smselem+=\; } } } else //nem alfanumerikus kodolas { //nem implementalt smselem+="Nem alfanumerikus"; } } else if (typ==7) //Tarolt uzenet { //fejlec atugrasa k+=6; //SC (00) //MTI (01) //MR (FF) //Dest.

Address (0080) //PID (00) //date coding scheme: alfanumerikus if ((0==((unsigned char)DataOut[k]&0xcc))||(0xf0==((unsigned char)DataOut[k]&0xf4))) { k++; char dekodoltszoveg[255]; int hossz=(unsigned char)DataOut[k]; DekodAlfanum(DataOut, k+1, hossz, dekodoltszoveg); for (i=0; i<hossz; i++) { if ((dekodoltszoveg[i]!=0x0a)&&(dekodoltszoveg[i]!=0x0d)) { smselem+=dekodoltszoveg[i]; } else { smselem+=\; } } 190 } else { //nem alfanumerikus kodolas //nem implementalt smselem+="Nem alfanumerikus"; } } else { //mas tipusu uzenet //nem implementalt smselem+="Nem visszaállítható!"; } smselem+=" "; } Waiting(0); m Eredmeny=smselem; Invalidate(); UpdateWindow(); } else //Telefonszamok es Sajat szamok if (("Telefonszámok"==cardBytes)||("Saját számok"==cardBytes)) { FileID[0]=0x6f; if ("Telefonszámok"==cardBytes) FileID[1]=0x3a; else FileID[1]=0x40; Rekordmeret=0x1a; //szabvany //Rovid telefonszamok file

kivalasztasa if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); Waiting(0); return; } //Hossz ellenorzes (szabvany: 0x1a) if(myError=card.GetMessage(statussize, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } if (0x67==(unsigned char)DataOut[0]) { //elter a hossz! a helyes hossz a [1] helyen if (myError=card.GetMessage((unsigned char)DataOut[1], DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } } //rekordmeret Rekordmeret=(unsigned char)DataOut[16]; //foglalt osszes meret Rekorddb=(unsigned char)DataOut[5]+((unsigned char)DataOut[4])*256; if (0x00==Rekordmeret) { //Ha nulla,

akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); Waiting(0); return; } //darabszam Rekorddb/=Rekordmeret; CString telelem(""); char betu[3]; for (j=0; j<Rekorddb; j++) { //max db szamu telefonszam 191 //1 rekord beolvasasa if (myError=card.ReadRecord((char)j+1, 0x04, Rekordmeret, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); Waiting(0); return; } if ((0x98==(unsigned char)DataOut[0])&&(0x04==(unsigned char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ehhez a művelethez előbb fel kell oldani a PIN kódot!", "Hiba", MB OK); Waiting(0); return; } else if (0x67==(unsigned char)DataOut[0]) //ujabb ellenorzes! { //Hibas hossz Rekordmeret=(unsigned char)DataOut[1]; card.ReadRecord((char)j+1, 0x04, Rekordmeret, DataOut, sizeof(DataOut)); } else if ((0x90!=(unsigned char)DataOut[0])&&(0x00!=(unsigned char)DataOut[1])) {

//Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); Waiting(0); return; } //sorszam sprintf(betu, "%03d", j+1); telelem+=betu; telelem+=". "; int pointer=Rekordmeret+2-14; //utana a nev valtozo hosszusagu for(i=2; i<pointer; i++) { telelem+=GSMabc(DataOut[i]); } telelem+=" "; //BCD szamhossz (byte) //a pointer erre mutat, hogy hany szamjegy van //nemzetkozi elohivo (bit5) if ((0xff!=(unsigned char)DataOut[pointer])&&(0x10 & (unsigned char)DataOut[pointer+1])) telelem+=+; //egyebkent 0x81 altalaban //vegul a szam for(i=pointer+2; i<pointer+1+DataOut[pointer]; i++) {//fel vannak cserelve a szamjegyek betu[0]=((unsigned char)DataOut[i])%16; if (0x0f!=betu[0]) { if (0x0b==betu[0]) telelem+=#; else if (0x0c==betu[0]) telelem+=-; else if (0x0a==betu[0]) telelem+=*; else { betu[0]+=0x30; telelem+=betu[0]; } } betu[0]=((unsigned char)DataOut[i])/16; if (0x0f!=betu[0]) { if

(0x0b==betu[0]) telelem+=#; else if (0x0c==betu[0]) telelem+=-; else if (0x0a==betu[0]) telelem+=*; else { betu[0]+=0x30; telelem+=betu[0]; } } } telelem+=" "; 192 } Waiting(0); m Eredmeny=telelem; Invalidate(); UpdateWindow(); } } void CVC6SampleDlg::OnSzerkeszt() { // TODO: Add your control notification handler code here EditDlg dlgedit; dlgedit.pardlg=this; //Melyik van kivalasztva int Temakor=m TemaEdit.GetCurSel(); m TemaEdit.GetLBText(Temakor, dlgeditTemakor); int nResponse = dlgedit.DoModal(); if (nResponse == IDOK) { //Modositasok megtortentek } } int CVC6SampleDlg::Beolvas(int ssz, int &del, char *szam, char ido, char text) { int i,k; int Rekordmeret, Rekorddb; Error myError; char DataOut[255] = {0}; char FileID[2]={0x7f,0x10}; //Select directory TELECOM //A TELECOM konyvtar kivalasztasa (7f10) if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if

(0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //Minden file "rekord" formatumu bejegyzeseket tartalmaz CString Temakor(""); m TemaEdit.GetLBText(m TemaEditGetCurSel(), Temakor); //SMS if ("SMS (Rövid szöveges üzenetek)"==Temakor) { FileID[0]=0x6f; FileID[1]=0x3c; //SMS file kivalasztasa if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //Hossz ellenorzes (szabvany: 0xb0) if(myError=card.GetMessage(statussize, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x67==(unsigned char)DataOut[0]) { //elter a hossz! a

helyes hossz a [1] helyen 193 if (myError=card.GetMessage((unsigned char)DataOut[1], DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } } //rekordmeret Rekordmeret=(unsigned char)DataOut[16]; //foglalt osszes meret Rekorddb=(unsigned char)DataOut[5]+((unsigned char)DataOut[4])*256; if (0x00==Rekordmeret) { //Ha nulla, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //darabszam Rekorddb/=Rekordmeret; //ellenorzes if ((ssz<1)||(ssz>Rekorddb)) { MessageBox("A beírt sorszám nem megfelelő!", "Hiba", MB OK); return -1; } CString smselem(""); char betu[2]; //j=ssz-1; //1 rekord beolvasasa if (myError=card.ReadRecord((char)ssz, 0x04, Rekordmeret, DataOut, sizeof(DataOut))) { MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if ((0x98==(unsigned char)DataOut[0])&&(0x04==(unsigned

char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ehhez a művelethez előbb fel kell oldani a PIN kódot!", "Hiba", MB OK); return -1; } //feldolgozas k=2; //tipus int typ; switch ((unsigned char)DataOut[k++]) { case 0: del=TRUE; typ=0; break; case 1: del=FALSE; typ=1; break; case 3: del=FALSE; typ=3; break; case 5: del=FALSE; typ=5; break; case 7: del=FALSE; typ=7; break; } if { (typ==0) char)DataOut[k+3])) //Torolt uzenet //megprobaljuk visszaallitani if ((0x00==(unsigned char)DataOut[k])&&(0x00==(unsigned //Tarolt uzenet volt {//Service Centre:0 of Address: 0 194 Length char)DataOut[k])) typ=7; } else if ((0x00!=(unsigned char)DataOut[k])&&(0xff!=(unsigned //Olvasott uzenet volt {//Service Centre: nem 0 es nem ervenytelen (ff) typ=1; } } //ha ertelmes az uzenet if ((typ==1)||(typ==3)) { //Service Center int skipc=(unsigned char)DataOut[k++]; k+=skipc; // TP-MTI k++; //kuldo // international format national

format if ((0x91==(unsigned char)DataOut[k+1])||(0xa1==(unsigned char)DataOut[k+1])) //normal BCD { for(i=k+2; i<k+2+((unsigned char)DataOut[k]+1)/2; i++) {//fel vannak cserelve a szamjegyek betu[0]=((unsigned char)DataOut[i])%16; if (0x0f!=betu[0]) { betu[0]+=0x30; smselem+=betu[0]; } betu[0]=((unsigned char)DataOut[i])/16; if (0x0f!=betu[0]) { betu[0]+=0x30; smselem+=betu[0]; } } } else if (0xd0==(unsigned char)DataOut[k+1]) //alfanumerikus { char cim[20]; int cimhossz=((unsigned char)DataOut[k]*4)/7; DekodAlfanum(DataOut, k+2, cimhossz, cim); for (i=0; i<cimhossz; i++) smselem+=cim[i]; } else { //nem tamogatott formatumu cim smselem+="Ismeretlen"; } k+=2+((unsigned char)DataOut[k]+1)/2; //szamok atugrasa sprintf(szam, "%s", smselem); smselem.Empty(); //TP-PID k++; //date coding scheme: alfanumerikus if ((0==((unsigned char)DataOut[k]&0xcc))||(0xf0==((unsigned char)DataOut[k]&0xf4))) { k++; //Time-stamp smselem+=""; //ev

betu[0]=0x30+((unsigned char)DataOut[k])%16; smselem+=betu[0]; betu[0]=0x30+((unsigned char)DataOut[k++])/16; smselem+=betu[0]; smselem+="."; //honap betu[0]=0x30+((unsigned char)DataOut[k])%16; smselem+=betu[0]; betu[0]=0x30+((unsigned char)DataOut[k++])/16; 195 smselem+=betu[0]; smselem+="."; //nap betu[0]=0x30+((unsigned smselem+=betu[0]; betu[0]=0x30+((unsigned smselem+=betu[0]; smselem+=". "; //ora betu[0]=0x30+((unsigned smselem+=betu[0]; betu[0]=0x30+((unsigned smselem+=betu[0]; smselem+=":"; //perc betu[0]=0x30+((unsigned smselem+=betu[0]; betu[0]=0x30+((unsigned smselem+=betu[0]; smselem+=":"; //masodperc betu[0]=0x30+((unsigned smselem+=betu[0]; betu[0]=0x30+((unsigned smselem+=betu[0]; char)DataOut[k])%16; char)DataOut[k++])/16; char)DataOut[k])%16; char)DataOut[k++])/16; char)DataOut[k])%16; char)DataOut[k++])/16; char)DataOut[k])%16; char)DataOut[k++])/16; sprintf(ido, "%s", smselem); smselem.Empty();

k++; //idozona char dekodoltszoveg[255]; int hossz=(unsigned char)DataOut[k]; DekodAlfanum(DataOut, k+1, hossz, dekodoltszoveg); for (i=0; i<hossz; i++) { if ((dekodoltszoveg[i]!=0x0a)&&(dekodoltszoveg[i]!=0x0d)) { smselem+=dekodoltszoveg[i]; } else { smselem+=" "; } } } else //nem alfanumerikus kodolas { //nem implementalt smselem+="Nem alfanumerikus"; } } else if (typ==7) //Tarolt uzenet { //fejlec atugrasa k+=6; //SC (00) //MTI (01) //MR (FF) //Dest. Address (0080) //PID (00) //date coding scheme: alfanumerikus if ((0==((unsigned char)DataOut[k]&0xcc))||(0xf0==((unsigned char)DataOut[k]&0xf4))) { k++; char dekodoltszoveg[255]; int hossz=(unsigned char)DataOut[k]; DekodAlfanum(DataOut, k+1, hossz, dekodoltszoveg); for (i=0; i<hossz; i++) { 196 if ((dekodoltszoveg[i]!=0x0a)&&(dekodoltszoveg[i]!=0x0d)) { smselem+=dekodoltszoveg[i]; } else { smselem+=" "; } } } else //nem alfanumerikus kodolas { //nem implementalt

smselem+="Nem alfanumerikus"; } } else { //mas tipusu uzenet //nem implementalt smselem+="Nem visszaállítható!"; } sprintf(text, "%s", smselem); return 0; } else //Telefonszamok es Sajat szamok if (("Telefonszámok"==Temakor)||("Saját számok"==Temakor)) { FileID[0]=0x6f; if ("Telefonszámok"==Temakor) FileID[1]=0x3a; else FileID[1]=0x40; Rekordmeret=0x1a; //szabvany //Rovid telefonszamok file kivalasztasa if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //Hossz ellenorzes (szabvany: 0x1a) if(myError=card.GetMessage(statussize, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if

(0x67==(unsigned char)DataOut[0]) { //elter a hossz! a helyes hossz a [1] helyen if (myError=card.GetMessage((unsigned char)DataOut[1], DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } } //rekordmeret Rekordmeret=(unsigned char)DataOut[16]; //foglalt osszes meret Rekorddb=(unsigned char)DataOut[5]+((unsigned char)DataOut[4])*256; if (0x00==Rekordmeret) { //Ha nulla, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //darabszam Rekorddb/=Rekordmeret; //ellenorzes if ((ssz<1)||(ssz>Rekorddb)) { MessageBox("A beírt sorszám nem megfelelő!", "Hiba", MB OK); return -1; 197 } CString telelem(""); char betu[3]; //1 rekord beolvasasa if (myError=card.ReadRecord((char)ssz, 0x04, Rekordmeret, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if ((0x98==(unsigned

char)DataOut[0])&&(0x04==(unsigned char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ehhez a művelethez előbb fel kell oldani a PIN kódot!", "Hiba", MB OK); return -1; } else if (0x67==(unsigned char)DataOut[0]) //ujabb ellenorzes! { //Hibas hossz Rekordmeret=(unsigned char)DataOut[1]; card.ReadRecord((char)ssz, 0x04, Rekordmeret, DataOut, sizeof(DataOut)); } else if ((0x90!=(unsigned char)DataOut[0])&&(0x00!=(unsigned char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //ures-e? if (0xff==(unsigned char)DataOut[2]) del=1; else del=0; int pointer=Rekordmeret+2-14; //a nev valtozo hosszusagu for(i=2; i<pointer; i++) { telelem+=GSMabc(DataOut[i]); } sprintf(text, "%s", telelem); telelem.Empty(); //BCD szamhossz (byte) //a pointer erre mutat, hogy hany szamjegy van //nemzetkozi elohivo (bit5) if ((0xff!=(unsigned

char)DataOut[pointer])&&(0x10 & (unsigned char)DataOut[pointer+1])) telelem+=+; //egyebkent 0x81 altalaban //vegul a szam for(i=pointer+2; i<pointer+1+DataOut[pointer]; i++) {//fel vannak cserelve a szamjegyek betu[0]=((unsigned char)DataOut[i])%16; if (0x0f!=betu[0]) { if (0x0b==betu[0]) telelem+=#; else if (0x0c==betu[0]) telelem+=-; else if (0x0a==betu[0]) telelem+=*; else { betu[0]+=0x30; telelem+=betu[0]; } } betu[0]=((unsigned char)DataOut[i])/16; if (0x0f!=betu[0]) { if (0x0b==betu[0]) telelem+=#; else if (0x0c==betu[0]) telelem+=-; else if (0x0a==betu[0]) telelem+=*; else { betu[0]+=0x30; telelem+=betu[0]; } 198 } } sprintf(szam, "%s", telelem); return 0; } return -1; } int CVC6SampleDlg::Kiir(int ssz, int del, char *szam, char ido, char text) { int i,k,c; int skipc; int Rekordmeret, Rekorddb; Error myError; char DataOut[255] = {0}; char DataIn[255]= {0}; char FileID[2]={0x7f,0x10}; //Select directory TELECOM //A TELECOM konyvtar kivalasztasa

(7f10) if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //Minden file "rekord" formatumu bejegyzeseket tartalmaz CString Temakor(""); m TemaEdit.GetLBText(m TemaEditGetCurSel(), Temakor); //SMS if ("SMS (Rövid szöveges üzenetek)"==Temakor) { FileID[0]=0x6f; FileID[1]=0x3c; //SMS file kivalasztasa if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //Hossz ellenorzes (szabvany: 0xb0) if(myError=card.GetMessage(statussize, DataOut,

sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x67==(unsigned char)DataOut[0]) { //elter a hossz! a helyes hossz a [1] helyen if (myError=card.GetMessage((unsigned char)DataOut[1], DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } } //rekordmeret Rekordmeret=(unsigned char)DataOut[16]; //foglalt osszes meret Rekorddb=(unsigned char)DataOut[5]+((unsigned char)DataOut[4])*256; if (0x00==Rekordmeret) { //Ha nulla, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //darabszam Rekorddb/=Rekordmeret; 199 //ellenorzes if ((ssz<1)||(ssz>Rekorddb)) { MessageBox("A beírt sorszám nem megfelelő!", "Hiba", MB OK); return -1; } char betu[2]; //a rekord beolvasasa if (myError=card.ReadRecord((char)ssz, 0x04, Rekordmeret, DataOut, sizeof(DataOut))) { MessageBox("A kártya nem

olvasható!", "Hiba", MB OK); return -1; } if ((0x98==(unsigned char)DataOut[0])&&(0x04==(unsigned char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ehhez a művelethez előbb fel kell oldani a PIN kódot!", "Hiba", MB OK); return -1; } // ---- feldolgozas ------------------------------------------------------------k=2; i=0; //beolvasott //kiirando //kuldo? int type; int subtype; if (szam[0]==) //nincs felado { //sajat type=7; } else //van felado { //elozo uzenet milyen volt switch ((unsigned char)DataOut[k]) { case 0: //Torolt uzenet //megprobaljuk visszaallitani if ((0x00==(unsigned char)DataOut[k])&&(0x00==(unsigned char)DataOut[k+3])) //Tarolt uzenet volt {//Service Centre:0 Length of Address: 0 subtype=7; } else if ((0x00!=(unsigned char)DataOut[k])&&(0xff!=(unsigned char)DataOut[k])) //Olvasott uzenet volt {//Service Centre: nem 0 es nem ervenytelen (ff) subtype=1; } else subtype=7; break;

case 1: subtype=1; break; case 3: subtype=3; break; default: subtype=7; break; } type=3; //az uj uzenet olvasatlan lesz } //uzenet tipusa if (del) DataIn[i]=0; else DataIn[i]=type; k++; i++; 200 //ha fogadott uzenet if (type==3) { //Service Center if (subtype!=7) //megtarthato az eredeti SC { skipc=(unsigned char)DataOut[k++]; DataIn[i++]=skipc; for(c=0; c<skipc; c++) { DataIn[i++]=(unsigned char)DataOut[k++]; } } else { //uj SC::=6307999999f9 DataIn[i++]=0x07; DataIn[i++]=0x91; DataIn[i++]=0x63; DataIn[i++]=0x07; DataIn[i++]=0x99; DataIn[i++]=0x99; DataIn[i++]=0x99; DataIn[i++]=0xf9; k++; } // TP-MTI k++; DataIn[i++]=0x04; //kuldo skipc=(unsigned char)DataOut[k++]; //szamjegyek szama int cspace=0; //nem szamjegyek szama for (c=0; ((c<20)&&(szam[c]!=)); c++) if ((szam[c]<0)||(szam[c]>9)) cspace++; k++; if (atoi(szam)!=0) { DataIn[i++]=c-cspace;; DataIn[i++]=0x91;// international format betu[1]=0x01; DataIn[i]=0; for(c=0; szam[c]!=; c++) {//fel vannak

cserelve a szamjegyek if ((szam[c]!= )&&(szam[c]!=+)) { if (#==szam[c]) betu[0]=betu[1]*0x0b; else if (-==szam[c]) betu[0]=betu[1]*0x0c; else if (*==szam[c]) betu[0]=betu[1]0x0a; else if ((0<=szam[c])&&(9>=szam[c])) betu[0]=betu[1]*(szam[c]-0x30); else { MessageBox("A beírt telefonszám nem megfelelő!", "Hiba", MB OK); return -1; } DataIn[i]+=betu[0]; if (betu[1]==0x01) betu[1]=0x10; else { betu[1]=0x01; //most egy byte ugras DataIn[++i]=0; } } } //ha lemaradt egy szamjegy if (betu[1]==0x10) DataIn[i++]+=0xf0; DataIn[i++]=0x00; DataIn[i++]=0x00; } 201 //TP-PID //TP-DCS else { DataIn[i++]=(((c+1)*7)/8)2; DataIn[i++]=0xd0; //alfanumerikus Alfanum(DataIn, i, szam); i+=((c+1)*7)/8; //ennyin fert el DataIn[i++]=0x39; //TP-PID DataIn[i++]=0xf1; //TP-DCS } k+=2+(skipc+1)/2; //szamok atugrasa //Time-stamp //XX.YYZZ AA:BB:CC //ev betu[0]=ido[1]-0x30; betu[0]+=(ido[2]-0x30)*0x10; DataIn[i++]=betu[0]; //honap betu[0]=ido[4]-0x30;

betu[0]+=(ido[5]-0x30)*0x10; DataIn[i++]=betu[0]; //nap betu[0]=ido[7]-0x30; betu[0]+=(ido[8]-0x30)*0x10; DataIn[i++]=betu[0]; //ora betu[0]=ido[11]-0x30; betu[0]+=(ido[12]-0x30)*0x10; DataIn[i++]=betu[0]; //perc betu[0]=ido[14]-0x30; betu[0]+=(ido[15]-0x30)*0x10; DataIn[i++]=betu[0]; //masodperc betu[0]=ido[17]-0x30; betu[0]+=(ido[18]-0x30)*0x10; DataIn[i++]=betu[0]; //idozona DataIn[i++]=4; //+4*15 Min //betuk szama for (c=0; ((c<200)&&(text[c]!=)); c++); DataIn[i++]=c; //szoveg Alfanum(DataIn, i, text); } else if (type==7) //Tarolt uzenet { //fejlec DataIn[i++]=0; //SC (00) DataIn[i++]=1; //MTI (01) DataIn[i++]=0xff; //MR (FF) DataIn[i++]=0; //Dest. Address (0080) DataIn[i++]=8; //sajat DataIn[i++]=0; //PID (00) DataIn[i++]=0; //DCS (00) //betuk szama for (c=0; ((c<200)&&(text[c]!=)); c++); DataIn[i++]=c; //szoveg Alfanum(DataIn, i, text); } else { //mas tipusu uzenet //nem implementalt return -1; } //kiiras a kartyara //1 rekord kiirasa if

(myError=card.WriteRecord((char)ssz, 0x04, Rekordmeret, DataIn, DataOut, sizeof(DataOut))){ 202 MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if ((0x98==(unsigned char)DataOut[0])&&(0x04==(unsigned char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ehhez a művelethez előbb fel kell oldani a PIN kódot!", "Hiba", MB OK); return -1; } else if (0x67==(unsigned char)DataOut[0]) //ujabb ellenorzes! { //Hibas hossz Rekordmeret=(unsigned char)DataOut[1]; card.ReadRecord((char)ssz, 0x04, Rekordmeret, DataOut, sizeof(DataOut)); } else if ((0x90!=(unsigned char)DataOut[0])&&(0x00!=(unsigned char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } return 0; } else //Telefonszamok es Sajat szamok if (("Telefonszámok"==Temakor)||("Saját számok"==Temakor)) { FileID[0]=0x6f; if

("Telefonszámok"==Temakor) FileID[1]=0x3a; else FileID[1]=0x40; Rekordmeret=0x1a; //szabvany //Rovid telefonszamok file kivalasztasa if(myError=card.SelectFile(FileID, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x9f!=(unsigned char)DataOut[0]) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //Hossz ellenorzes (szabvany: 0x1a) if(myError=card.GetMessage(statussize, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if (0x67==(unsigned char)DataOut[0]) { //elter a hossz! a helyes hossz a [1] helyen if (myError=card.GetMessage((unsigned char)DataOut[1], DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } } //rekordmeret Rekordmeret=(unsigned char)DataOut[16]; //foglalt osszes meret

Rekorddb=(unsigned char)DataOut[5]+((unsigned char)DataOut[4])*256; if (0x00==Rekordmeret) { //Ha nulla, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } //darabszam Rekorddb/=Rekordmeret; //ellenorzes if ((ssz<1)||(ssz>Rekorddb)) { MessageBox("A beírt sorszám nem megfelelő!", "Hiba", MB OK); return -1; } char betu[3]; 203 //eloszor torli a meglevo adatokat for (i=0; i<Rekordmeret; i++) DataIn[i]=0xff; if (!del) {//nem ures int pointer=Rekordmeret-14; //a nev valtozo hosszusagu text[pointer]=; //max ilyen hosszu for (i=0; text[i]!=; i++) { DataIn[i]=ReGSMabc(text[i]); } //BCD szamhossz (byte) //a pointer erre mutat, hogy hany byte-nyi szamjegy van int cspace=0; //hany space for (i=0; ((i<20)&&(szam[i]!=)); i++) if (szam[i]== ) cspace++; if (i>24) i=24; //max 24 jegy lehet DataIn[pointer]=1+(i-cspace+1)/2; //nemzetkozi elohivo (bit5 -> 0x91) if (szam[0]==+) DataIn[pointer+1]=0x91; else

DataIn[pointer+1]=0x81; //egyebkent 0x81 altalaban //vegul a szam i=pointer+2; betu[1]=0x01; DataIn[i]=0; for(c=0; szam[c]!=; c++) {//fel vannak cserelve a szamjegyek if ((szam[c]!= )&&(szam[c]!=+)) { if (#==szam[c]) betu[0]=betu[1]*0x0b; else if (-==szam[c]) betu[0]=betu[1]*0x0c; else if (*==szam[c]) betu[0]=betu[1]0x0a; else if ((0<=szam[c])&&(9>=szam[c])) betu[0]=betu[1]*(szam[c]-0x30); else { MessageBox("A beírt telefonszám nem megfelelő!", "Hiba", MB OK); return -1; } DataIn[i]+=betu[0]; if (betu[1]==0x01) betu[1]=0x10; else { betu[1]=0x01; //most egy byte ugras DataIn[++i]=0; } } } //ha lemaradt egy szamjegy if (betu[1]==0x10) DataIn[i++]+=0xf0; } //kiiras a kartyara //1 rekord kiirasa if (myError=card.WriteRecord((char)ssz, 0x04, Rekordmeret, DataIn, DataOut, sizeof(DataOut))){ MessageBox("A kártya nem olvasható!", "Hiba", MB OK); return -1; } if ((0x98==(unsigned char)DataOut[0])&&(0x04==(unsigned

char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ehhez a művelethez előbb fel kell oldani a PIN kódot!", "Hiba", MB OK); return -1; } else if (0x67==(unsigned char)DataOut[0]) //ujabb ellenorzes! { //Hibas hossz Rekordmeret=(unsigned char)DataOut[1]; card.ReadRecord((char)ssz, 0x04, Rekordmeret, DataOut, sizeof(DataOut)); 204 } else if ((0x90!=(unsigned char)DataOut[0])&&(0x00!=(unsigned char)DataOut[1])) { //Ha nem lehet kivalasztani, akkor gond van MessageBox("Ismeretlen hiba!", "Hiba", MB OK); return -1; } return 0; } return -1; } 8.210 VC6SampleDlgh Az előző fájlhoz tartozó header fájl. Fontos, hogy az új lekezelendő üzenet miatt az afx msg LRESULT OnStatusChanged(WPARAM wParam, LPARAM lParam); sort is hozzáadjuk a definícióhoz. // VC6SampleDlg.h : header file // #if !defined(AFX VC6SAMPLEDLG H 384992C7 F8F8 11D3 B375 006008CD4928 INCLUDED ) #define AFX VC6SAMPLEDLG H 384992C7 F8F8

11D3 B375 006008CD4928 INCLUDED #include "Scard.h" // Added by ClassView #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 ///////////////////////////////////////////////////////////////////////////// // CVC6SampleDlg dialog class CVC6SampleDlg : public CDialog { // Construction public: CVC6SampleDlg(CWnd* pParent = NULL); // standard constructor int Beolvas(int ssz, int &del, char *szam, char ido, char text); int Kiir(int ssz, int del, char *szam, char ido, char text); CScard card; // Dialog Data //{{AFX DATA(CVC6SampleDlg) enum { IDD = IDD VC6SAMPLE DIALOG }; CEdit m ListEdit; CComboBox m TemaEdit; CButton m SetChkPin; CEdit m pinEdit; CString m pin; int m Psorszam; BOOL m Pinactive; CString m Eredmeny; //}}AFX DATA // ClassWizard generated virtual function overrides //{{AFX VIRTUAL(CVC6SampleDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX VIRTUAL // Implementation protected: int CheckSIM(); void

GetSIMSerial(); int GetSIMProvider(char *prname); void Waiting(int state); CString serial; int waitstate; int Pin1maradt; 205 int Pin2maradt; int statussize; HICON m hIcon; // Generated message map functions //{{AFX MSG(CVC6SampleDlg) virtual BOOL OnInitDialog(); afx msg void OnPaint(); afx msg HCURSOR OnQueryDragIcon(); afx msg void OnRead(); afx msg void OnVerify(); afx msg void OnRefresh(); afx msg void OnRadiopin1(); afx msg void OnRadiopin2(); afx msg void OnCheckpinaktiv(); afx msg void OnSzerkeszt(); //}}AFX MSG afx msg LRESULT OnStatusChanged(WPARAM wParam, LPARAM lParam); DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX VC6SAMPLEDLG H 384992C7 F8F8 11D3 B375 006008CD4928 INCLUDED ) 8.211 EditDlgcpp A szerkesztésre használt dialógusablak implementációja az alábbi fájl. Az OnBeolvas() és OnKiir() funkciók végzik a már említett

rekordkezelést, meghívják a szülőablak hasonló nevű függvényeit, ehhez persze be kell állítani a pardlg változó értékét, ezt azonban a dialógusablakot létrehozó VC6SampleDlg.cpp fájlban az OnSzerkeszt() funkció már elvégezte. A további függvények a megadott paraméterek kezeléséért felelősek. // EditDlg.cpp : implementation file // #include #include #include #include "stdafx.h" "VC6Sample.h" "VC6SampleDlg.h" "EditDlg.h" #ifdef DEBUG #define new DEBUG NEW #undef THIS FILE static char THIS FILE[] = FILE ; #endif ///////////////////////////////////////////////////////////////////////////// // EditDlg dialog EditDlg::EditDlg(CWnd* pParent /=NULL/) : CDialog(EditDlg::IDD, pParent) { //{{AFX DATA INIT(EditDlg) m Deleted = FALSE; m Text = T(""); m TSzam = T(""); m Sorszam = 1; m Ido = T(""); //}}AFX DATA INIT } void EditDlg::DoDataExchange(CDataExchange* pDX) { 206

CDialog::DoDataExchange(pDX); //{{AFX DATA MAP(EditDlg) DDX Control(pDX, IDC SSZSCROLL, m SszScroll); DDX Control(pDX, IDC DELETED, m DelChk); DDX Control(pDX, IDC IDO, m IdoEdit); DDX Control(pDX, IDC SZOVEGMEZO, m TextEdit); DDX Control(pDX, IDC TSZAM, m TSzamEdit); DDX Check(pDX, IDC DELETED, m Deleted); DDX Text(pDX, IDC SZOVEGMEZO, m Text); DDV MaxChars(pDX, m Text, 200); DDX Text(pDX, IDC TSZAM, m TSzam); DDV MaxChars(pDX, m TSzam, 12); DDX Text(pDX, IDC SORSZAM, m Sorszam); DDV MinMaxInt(pDX, m Sorszam, 1, 999); DDX Text(pDX, IDC IDO, m Ido); DDV MaxChars(pDX, m Ido, 19); //}}AFX DATA MAP } BEGIN MESSAGE MAP(EditDlg, CDialog) //{{AFX MSG MAP(EditDlg) ON BN CLICKED(IDC BEOLVAS, OnBeolvas) ON BN CLICKED(IDC KIIR, OnKiir) ON BN CLICKED(IDC DELETED, OnDeleted) ON EN CHANGE(IDC IDO, OnChangeIdo) ON EN CHANGE(IDC SORSZAM, OnChangeSorszam) ON EN CHANGE(IDC SZOVEGMEZO, OnChangeSzoveg) ON WM PAINT() ON NOTIFY(UDN DELTAPOS, IDC SSZSCROLL, OnDeltaposSszscroll) ON EN CHANGE(IDC TSZAM,

OnChangeTszam) //}}AFX MSG MAP END MESSAGE MAP() ///////////////////////////////////////////////////////////////////////////// // EditDlg message handlers BOOL EditDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here m TextEdit.LimitText(200); m TSzamEdit.LimitText(12); m IdoEdit.LimitText(19); m SszScroll.SetRange(1,250); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void EditDlg::OnBeolvas() { int i; char szam[20]=""; char ido[20]=""; char text[200]=""; //Uresre allitjuk a listat m Text.Empty(); m TSzam.Empty(); m Ido.Empty(); m Deleted=FALSE; //Minden file "rekord" formatumu bejegyzeseket tartalmaz //SMS if ("SMS (Rövid szöveges üzenetek)"==Temakor) { if (pardlg->Beolvas(m Sorszam, m Deleted, szam, ido, text)) {//Hiba!!! Invalidate(); UpdateWindow(); 207 return; } for (i=0; ((i<20)&&(szam[i]!=));

i++) { m TSzam+=szam[i]; } for (i=0; ((i<20)&&(ido[i]!=)); i++) { m Ido+=ido[i]; } for (i=0; ((i<200)&&(text[i]!=)); i++) { m Text+=text[i]; } Invalidate(); UpdateWindow(); } else //Telefonszamok es Sajat szamok if (("Telefonszámok"==Temakor)||("Saját számok"==Temakor)) { if (pardlg->Beolvas(m Sorszam, m Deleted, szam, ido, text)) {//Hiba!!! Invalidate(); UpdateWindow(); return; } for (i=0; ((i<20)&&(szam[i]!=)); i++) { m TSzam+=szam[i]; } for (i=0; ((i<200)&&(text[i]!=)); i++) { m Text+=text[i]; } Invalidate(); UpdateWindow(); } } void EditDlg::OnKiir() { int i; char szam[20]=""; char ido[20]=""; char text[200]=""; int error=0; sprintf(szam, "%s", m TSzam); if ((m TSzam.IsEmpty()==0)&&("SMS (Rövid szöveges üzenetek)"==Temakor)) { if (m Ido.GetLength()<19) error=1; else { if (m Ido[0]!=0x27) error=1; if (m Ido[3]!=.) error=1; if (m Ido[6]!=.)

error=1; if (m Ido[9]!=.) error=1; if (m Ido[10]!= ) error=1; if (m Ido[13]!=:) error=1; if (m Ido[16]!=:) error=1; } } 208 if (1==error) { MessageBox("Hibás az időformátum! Helyesen YY.MMDD HH:MM:SS ", "Hiba"); return; } sprintf(ido, "%s", m Ido); int c=0; for (i=0; i<m Text.GetLength(); i++) {//Soremeles: 0x0a karakter csak!!! if (m Text[i]!=0x0d) text[c++]=m Text[i]; } if (pardlg->Kiir(m Sorszam, m Deleted, szam, ido, text)) {//Hiba!!! return; } } void EditDlg::OnDeleted() { // TODO: Add your control notification handler code here m Deleted=!m Deleted; } void EditDlg::OnChangeIdo() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM CHANGE flag ORed into the mask. // TODO: Add your control notification handler code here GetDlgItemText(IDC IDO, m Ido); } void EditDlg::OnChangeSorszam() { //

TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM CHANGE flag ORed into the mask. // TODO: Add your control notification handler code here int temp=(int)GetDlgItemInt(IDC SORSZAM); if ((temp<1)||(temp>999)) return; else { m Sorszam=temp; } } void EditDlg::OnChangeSzoveg() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM CHANGE flag ORed into the mask. // TODO: Add your control notification handler code here GetDlgItemText(IDC SZOVEGMEZO, m Text); } void EditDlg::OnChangeTszam() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM

CHANGE flag ORed into the mask. 209 // TODO: Add your control notification handler code here GetDlgItemText(IDC TSZAM, m TSzam); } void EditDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here SetDlgItemInt(IDC SORSZAM, m Sorszam); SetDlgItemText(IDC TSZAM, m TSzam); SetDlgItemText(IDC IDO, m Ido); SetDlgItemText(IDC SZOVEGMEZO, m Text); m DelChk.SetCheck(m Deleted); // Do not call CDialog::OnPaint() for painting messages } void EditDlg::OnDeltaposSszscroll(NMHDR* pNMHDR, LRESULT pResult) { NM UPDOWN* pNMUpDown = (NM UPDOWN)pNMHDR; // TODO: Add your control notification handler code here *pResult = 0; } 8.212 EditDlgh Az előző fájl deklarációit tartalmazó header fájl. #if !defined(AFX EDITDLG H 6623DE64 20F6 11D8 90AF 000AE642C6C5 INCLUDED ) #define AFX EDITDLG H 6623DE64 20F6 11D8 90AF 000AE642C6C5 INCLUDED #include "VC6SampleDlg.h" #if MSC VER > 1000 #pragma once #endif // MSC VER > 1000 //

EditDlg.h : header file // ///////////////////////////////////////////////////////////////////////////// // EditDlg dialog class EditDlg : public CDialog { // Construction public: EditDlg(CWnd* pParent = NULL); // standard constructor CString Temakor; CVC6SampleDlg *pardlg; // Dialog Data //{{AFX DATA(EditDlg) enum { IDD = IDD EDITDLG }; CSpinButtonCtrl m SszScroll; CButton m DelChk; CEdit m IdoEdit; CEdit m TextEdit; CEdit m TSzamEdit; BOOL m Deleted; CString m Text; CString m TSzam; int m Sorszam; CString m Ido; //}}AFX DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX VIRTUAL(EditDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX VIRTUAL 210 // Implementation protected: // Generated message map functions //{{AFX MSG(EditDlg) afx msg void OnBeolvas(); afx msg void OnKiir(); virtual BOOL OnInitDialog(); afx msg void OnDeleted(); afx msg void OnChangeIdo(); afx msg void OnChangeSorszam(); afx msg void

OnChangeSzoveg(); afx msg void OnPaint(); afx msg void OnDeltaposSszscroll(NMHDR* pNMHDR, LRESULT pResult); afx msg void OnChangeTszam(); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX EDITDLG H 6623DE64 20F6 11D8 90AF 000AE642C6C5 INCLUDED ) 8.213 Scardcpp Az alábbi fájl lényegét tekintve teljes mértékben azonos a Cardlist.exe forráskódjában szereplővel, csak ezt magyar nyelvű kommentekkel láttam el. 8.214 Scardh Az alábbi fájl szintén azonos a Cardlist.exe forráskódjában szereplővel, és szintén magyar nyelvű kommenteket tartalmaz 8.215 res/VC6Samplerc2 A manuálisan szerkeszthető erőforrásfájl automatikusan jön mindig létre. Jelenleg nem tartalmaz új komponenst. // // VC6SAMPLE.RC2 - resources Microsoft Visual C++ does not edit directly // #ifdef APSTUDIO INVOKED #error this file is not editable by Microsoft Visual

C++ #endif //APSTUDIO INVOKED ///////////////////////////////////////////////////////////////////////////// // Add manually edited resources here. ///////////////////////////////////////////////////////////////////////////// 211 8.216 res/VC6Sampleico A program nagy (32x32 képpont) és kis méretű (16x16 képpont) ikonjait tartalmazza. A Visual Studio ikonszerkesztőjével hoztam létre. 8.217 Scarderr Nem tartozik szorosan egyik programhoz sem. A Windows könyvtárban elhelyezkedő állomány az ScardServer hibaüzeneteit tartalmazza a támogatott nyelveken. A magyar nyelvű üzeneteket jómagam fordítottam le és mellékeltem a fájlhoz, tekintve, hogy korábbi verzió a magyar nyelvet még nem támogatta. Talán sikerült ezen változtatni, mivel felvettem a kapcsolatot az anyacéggel, és a fordítást elküldtem a számukra is Mindenesetre, a teljesen magyar nyelvű alkalmazáshoz illendő magyar nyelvű hibaüzeneteket is használni Egyébként a forráskódban is, a

nyelv megadásánál a [MAGYAR] szerepel, amely a már kiegészített Scarderr fájl használja [] [MAGYAR] 0000=OK 1001=A soros port nem elérhető 1002=A soros portot egy másik alkalmazás használja 1008=A kártyaolvasó nem elérhető 1009=#1 használja a kártyaolvasót 1010=Az alkalmazás nem kompatibilis a kártyaolvasóval 4000=Nincs kártya a kártyaolvasóban 4001=Hozzáférés közben a kártyát eltávolították 4002=Érvénytelen kártya 4004=A kártya kiadása nem lehetséges 1200=Érvénytelen utasítás 1201=A kártyán az adott utasítás nem használható 1202=A kártyaolvasón az adott utasítás nem használható 1203=Az utasítás paramétere hibás 1310=Hozzáférés megszakadt 1311=Hibás PIN kód! Még #1 próbálkozás maradt 1312=A PIN kód megadása megszakadt 1313=A PIN kód megadásához szükséges idő lejárt 2000=A kiszolgálóalkalmazás nem elérhető // A következő üzenetek lefordításánál vegyük figyelembe a lehetséges kombinációkat: //

Kártyaolvasó neve+9000 -> CHIPDRIVE micro a COM3 porton // 9001+9000 -> Keresés a COM3 porton // 9002+9000 -> Nem található eszköz a COM3 porton 9000=a COM#1 porton 9001=Keresés 9002=Nem található eszköz [] 212 IV. Mellékletek Ebben a fejezetben kerülnek bemutatásra a többi témakörhöz nem szorosan kapcsolódó, de kifejtést igénylő tárgykörök. 9. Licencszerződés Tekintve, hogy a „GSView” az Aladdin Free Public Licence alapján használható, nem térhetek el tőle én sem, így mivel a szoftverterméket nyomtatott anyag is kíséri, magát a licencszerződést is nyomtatott formában kell elérhetővé tenni. Emellett természetesen az eredeti forráskódhoz mellékelve elektronikus formában is elérhető a mellékelt CD-n. Az eredeti licencszerződés angol nyelvű. Egy magyar nyelvű szakdolgozathoz azonban véleményem szerint elengedhetetlen, hogy legalább kivonatos formában a magyar nyelvű fordítása is megjelenjen. Sajnos az

Interneten nem találtam meg ezt, így magam vállalkoztam a fordításra Nem kívánom, hogy a fordítást bárhol bárki is mérvadónak tekintse, ez csak egy általam létrehozott ajánlás, mely egy esetleges későbbi magyar verzió létrehozásához nyújthat segítséget Előbb az angol nyelvű eredeti, majd ennek magyar verziója következik. 213 Aladdin Free Public Licence (Version 7, June 4, 1998) Copyright (C) 1994, 1995, 1997, 1998 Aladdin Enterprises, Menlo Park, California, U.SA All rights reserved NOTE: This Licence is not the same as any of the GNU Licences published by the Free Software Foundation. Its terms are substantially different from those of the GNU Licences. If you are familiar with the GNU Licences, please read this licence with extra care. Aladdin Enterprises hereby grants to anyone the permission to apply this Licence to their own work, as long as the entire Licence (including the above notices and this paragraph) is copied with no changes, additions,

or deletions except for changing the first paragraph of Section 0 to include a suitable description of the work to which the licence is being applied and of the person or entity that holds the copyright in the work, and, if the Licence is being applied to a work created in a country other than the United States, replacing the first paragraph of Section 6 with an appropriate reference to the laws of the appropriate country. 0. Subject Matter This Licence applies to the computer program known as "GSview." The "Program", below, refers to such program. The Program is a copyrighted work whose copyright is held by Ghostgum Software Pty Ltd (the "Licensor"). A "work based on the Program" means either the Program or any derivative work of the Program, as defined in the United States Copyright Act of 1976, such as a translation or a modification. BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF

THIS LICENSE TO DO SO, AND ALL ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM. 1. Licences Licensor hereby grants you the following rights, provided that you comply with all of the restrictions set forth in this Licence and provided, further, that you distribute an unmodified copy of this Licence with the Program: (a) You may copy and distribute literal (i.e, verbatim) copies of the Programs source code as you receive it throughout the world, in any medium. (b) You may modify the Program, create works based on the Program and distribute copies of such throughout the world, in any medium. 214 2. Restrictions This licence is subject to the following restrictions: (a) Distribution of the Program or

any work based on the Program by a commercial organization to any third party is prohibited if any payment is made in connection with such distribution, whether directly (as in payment for a copy of the Program) or indirectly (as in payment for some service related to the Program, or payment for some product or service that includes a copy of the Program "without charge"; these are only examples, and not an exhaustive enumeration of prohibited activities). The following methods of distribution involving payment shall not in and of themselves be a violation of this restriction: (i) Posting the Program on a public access information storage and retrieval service for which a fee is received for retrieving information (such as an on-line service), provided that the fee is not content-dependent (i.e, the fee would be the same for retrieving the same volume of information consisting of random data) and that access to the service and to the Program is available independent of any

other product or service. An example of a service that does not fall under this section is an on-line service that is operated by a company and that is only available to customers of that company. (This is not an exhaustive enumeration) (ii) Distributing the Program on removable computer-readable media, provided that the files containing the Program are reproduced entirely and verbatim on such media, that all information on such media be redistributable for non-commercial purposes without charge, and that such media are distributed by themselves (except for accompanying documentation) independent of any other product or service. Examples of such media include CD-ROM, magnetic tape, and optical storage media (This is not intended to be an exhaustive list) An example of a distribution that does not fall under this section is a CD-ROM included in a book or magazine. (This is not an exhaustive enumeration.) (b) Activities other than copying, distribution and modification of the Program are

not subject to this Licence and they are outside its scope. Functional use (running) of the Program is not restricted, and any output produced through the use of the Program is subject to this licence only if its contents constitute a work based on the Program (independent of having been made by running the Program). (c) You must meet all of the following conditions with respect to any work that you distribute or publish that in whole or in part contains or is derived from the Program or any part thereof ("the Work"): (i) If you have modified the Program, you must cause the Work to carry prominent notices stating that you have modified the Programs files and the date of any change; (ii) You must cause the Work to be licensed as a whole and at no charge to all third parties under the terms of this Licence; (iii) If the Work normally reads commands interactively when run, you must cause it, at each time the Work commences operation, to print or display an announcement including

an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty). Such notice must also state that users may redistribute the Work only under the conditions of this Licence and tell the 215 user how to view the copy of this Licence included with the Work. (Exceptions: if the Program is interactive but normally prints or displays such an announcement only at the request of a user, such as in an "About box", the Work is required to print or display the notice only under the same circumstances; if the Program itself is interactive but does not normally print such an announcement, the Work is not required to print an announcement.); (iv) You must accompany the Work with the complete corresponding machinereadable source code, delivered on a medium customarily used for software interchange. The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source

code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable code. If you distribute with the Work any component that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, you must also distribute the source code of that component if you have it and are allowed to do so; (v) If you distribute any written or printed material at all with the Work, such material must include either a written copy of this Licence, or a prominent written indication that the Work is covered by this Licence and written instructions for printing and/or displaying the copy of the Licence on the distribution medium; (vi) You may not impose any further restrictions on the recipients exercise of the rights granted herein. If distribution of executable or object code is made by

offering the equivalent ability to copy from a designated place, then offering equivalent ability to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source code along with the object code. 3. Reservation of Rights No rights are granted to the Program except as expressly set forth herein. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this Licence. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this Licence However, parties who have received copies, or rights, from you under this Licence will not have their licences terminated so long as such parties remain in full compliance. 4. Other Restrictions If the distribution and/or use of the Program is restricted in certain countries for any reason, Licensor may add an explicit geographical distribution limitation

excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this Licence incorporates the limitation as if written in the body of this Licence. 216 5. Limitations THE PROGRAM IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY. THERE IS NO WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL LICENSOR, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR

INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 6. General This Licence is governed by the laws of the State of Victoria, Australia, excluding choice of law rules. If any part of this Licence is found to be in conflict with the law, that part shall be interpreted in its broadest meaning consistent with the law, and no other parts of the Licence shall be affected. 217 Aladdin szabad felhasználói licencszerződés (7. változat, 1998 június 4) Aladdin Enterprises, Menlo Park, California, U.SA 1994, 1995, 1997, 1998 Minden jog fenntartva! FIGYELMEZTETÉS: Ezen licencszerződés nem azonos semmilyen más, a Free Software Foundation által publikált GNU licencszerződéssel, ennek feltételei lényegesen eltérnek azoktól. Ha ön

találkozott már korábban is GNU licencszerződéssel, kérjük különös figyelemmel olvassa el e licencszerződést! Az Aladdin Enterprises ezúton hozzájárul ahhoz, hogy bárki alkalmazza ezen licencszerződést a saját munkájára mindaddig, amíg a teljes licencszerződést (beleértve a fenti figyelmeztetést és jelen bekezdést is) változtatások, kiegészítések, kihagyások nélkül mellékeli. Kivételt képez ez alól a 0 pont első bekezdése, mely megváltoztatható oly módon, hogy mellékelhető az elvégzett munka megfelelő leírása, melyre a licencszerződés vonatkozik, ugyanígy a szerzői jogot formáló természetes vagy jogi személy neve is. Ha a licencszerződés az Egyesült Államokon kívül, más országban elvégzett munkára vonatkozik, akkor továbbá a 6 pont első bekezdése helyettesíthető az aktuális ország megfelelő jogi rendelkezéseire való hivatkozással. 0. A szerződés tárgya Jelen licencszerződés a „GSview” nevű

számítógépes programra (továbbiakban „Program”) vonatkozik. A Program a szerzői jog által védett alkotás, melyre vonatkozó jogokkal a GhostGum Software Pty Ltd (továbbiakban „Licencadó”) él. A „Programból származó egyéb mű” alatt a továbbiakban magát a Programot vagy bármely a Programból származtatható alkotást értjük, az Amerikai Egyesült Államok 1976. évi Szerzői jogi törvénye alapján, úgymint lefordítás vagy módosítás A PROGRAM VAGY A PROGRAMBÓL SZÁRMAZÓ EGYÉB MŰ MÓDOSÍTÁSÁVAL VAGY TERJESZTÉSÉVEL ÖN ELFOGADJA JELEN LICENCSZERZŐDÉST ANNAK MINDEN ELŐÍRÁSÁVAL ÉS A PROGRAM VAGY A PROGRAMBÓL SZÁRMAZÓ EGYÉB MŰ MÁSOLÁSÁRA, TERJESZTÉSÉRE VAGY MÓDOSÍTÁSÁRA VONATKOZÓ FELTÉTELEKKEL EGYÜTT. KIZÁRÓLAG JELEN LICENCSZERZŐDÉS KERETÉBEN VÉGEZHETŐ A PROGRAM VAGY SZÁRMAZÉKAINAK MÓDOSÍTÁSA ÉS TERJESZTÉSE, MÁSKÜLÖKBEN EZEN CSELEKEDETEKET A TÖVÉNY TILTJA. HA ÖN NEM ÉRT EGYET EZEN FELTÉTELEKKEL

ÉS ELŐÍRÁSOKKAL, AKKOR SEMMIKÉPP NE MÓDOSÍTSA VAGY TERJESSZE A PROGRAMOT! 1. Licenc jogok A Licencadó ezúton a következő jogokat engedélyezi önnek, feltéve, hogy eleget tesz a licencszerződésben fennálló mindennemű előírásnak, és feltéve továbbá, hogy a Programhoz mellékeli jelen licencszerződés módosítatlan változatát. a) Ön másolhatja és terjesztheti bárhol a világon a Program forráskódját az elérhető, szó szerinti változatlan formában bármely adathordozón. 218 b) Ön módosíthatja a Programot, létrehozhat a Programból származó egyéb művet és terjesztheti ezeket bárhol a világon bármely adathordozón. 2. Korlátozások Ezen licencszerződés tárgyát képezik a további korlátozások: a) A Program vagy bármely a Programból származó egyéb mű terjesztése üzleti tevékenységet folytató szervezet számára tilos, ha ezzel kapcsolatban valamekkora fizetségre sor kerül, akár közvetlen módon (úgymint fizetni a

Program egy példányáért), akár közvetve (úgymint fizetni valamely szolgáltatásért a Programmal kapcsolatban), vagy olyan termékért vagy szolgáltatásért fizetni, amelyhez a Programot „ingyenesen” mellékelik (ezek csak szemléltető példák, a lista korántsem teljes). Csak a következő terjesztési módok azok, melyek fizetség mellett végrehajthatók jelen kikötések megsértése nélkül: i) A Program feltöltése valamely nyilvánosan hozzáférhető tárolóeszközre és a hozzáférésért cserébe bizonyos hozzáférési díj szedése (mint pl. on-line szolgáltatásként), azzal a feltétellel, hogy a díjösszeg nem tartalomfüggő (értsd: ugyanennyit kell fizetni bármely hasonló méretű, tetszőleges információt tartalmazó adatért cserébe) és mind a hozzáférési szolgáltatás, mind a Programhoz való hozzáférés elérhető minden más terméktől vagy szolgáltatástól függetlenül. Nem értendő ezen bekezdésbe az olyan on-line

szolgáltatás, melyet egy cég kizárólag saját alkalmazottainak nyújt. (A lista korántsem teljes) ii) A Program terjesztése hordozható számítógépes adathordozón, gondoskodva arról, hogy az érintett fájlok a Programot teljes mértékben és szó szerint változatlan formában tartalmazzák, és az adathordozón lévő összes adatot nem üzleti célból ingyenesen terjesszék, és az adathordozó terjesztése (eltekintve a kísérő dokumentációtól) minden más terméktől vagy szolgáltatástól független. Ilyen adathordozó pl. a CD-ROM, a mágneses szalag és az optikai tárolóegység (e lista azonban korántsem teljes) Nem értendő e bekezdésbe pl egy könyv vagy magazin CDmelléklete (számos más egyéb mellett) b) A másoláson, a terjesztésen és a módosításon kívül a Programmal kapcsolatos más tevékenység nem tárgya e licencszerződésnek és ezek tárgyalásától eltekintünk. A Program futtatása nincs feltételekhez kötve, és a Program

által létrehozott bármilyen kimeneti eredmény csak akkor tárgya jelen licencszerződésnek, ha annak tartalma a Programból származó egyéb művet képez (függetlenül attól, hogy a Program lefuttatásával készült). c) Ön köteles eleget tenni a következő feltételeknek, tekeintettel minden Ön által szerzett, kiadott vagy terjesztett műre, mely részben vagy egészben a Programot vagy annak valamely részét tartalmazza, vagy abból származtatható (a továbbiakban a „Mű”): i) Ha ön módosítja a Programot, köteles arra, hogy a Műben feltűnő figyelmeztetést helyezzen el arról, hogy módosította az eredeti Program fájljait és a módosítás dátumáról; ii) Köteles a Művet teljes egészében, harmadik személy részéről felmerülő mindennemű fizetség nélkül, e licencszerződés szerint továbblicencelni; iii)Ha a Mű egyébiránt interaktívan utasításokat kér futás közben, köteles minden alkalommal, amikor a Mű működésbe lép,

kiíratni vagy kinyomtatni egy értesítő 219 szöveget a megfelelő szerzői jogi figyelmeztetés kíséretében, és felhívni rá a figyelmet, hogy Műre semmi garancia nem vonatkozik (sem más egyéb, akár Ön által vállalt garancia). Ezen figyelmeztetésnek azt is tartalmaznia kell, hogy a felhasználók csak e licencszerződés értelmében terjeszthetik a Művet, valamint azt is közölnie kell a felhasználóval, hogy mi módon olvashatja el a Műhöz mellékelt e licencszerződést. (Kivétel: Ha a Program interaktív, de rendes körülmények között csak a felhasználó kérésére ír ki vagy nyomtat figyelmeztetéseket, mint pl „A programról” menüpontban, akkor a Műnek csak ugyanezen körülmények között kell a figyelmeztető szöveget kiírnia; ha a Program maga interaktív, de általában nem ír ki vagy nyomtat hasonló figyelmeztetéseket, a Műnek sem kell.); iv) Köteles a Művet kísérni a teljes megfelelő, számítógépen olvasható

forráskód olyan adathordozón, melyet szoftverek szállításához szokás használni. A forráskód alatt a Mű olyan ismert formáját értjük, hogy módosításokat lehessen rajta végezni. Egy futtatható állomány teljes forráskódja az általa tartalmazott összes modul komplett forráskódjait jelenti, emellett minden hozzákapcsolódó interfész definíciós fájlt a fordítást és a telepítést vezérlő szkriptekkel együtt. Ha a Mű mellett olyan komponensek találhatók forráskódban vagy binárisan, melyek általában a futtató operációs rendszer fő részeivel (fordító, kernel stb.) kerülnek forgalmazásra, akkor köteles rendelkezésre bocsátani e komponensek forráskódját, ha rendelkezik ezekkel és e cselekményt semmi nem gátolja; v) Ha a Művet bármely írott vagy nyomtatott anyag kíséri, köteles e licencszerződést is nyomtatott formában mellékelni, vagy feltűnő helyre olyan figyelmeztetést elhelyezni, mely kimondja, hogy a Mű

használatát e licencszerződés szabályozza, és instrukciókat tartalmaz arra nézve, hogyan lehet megtekinteni és/vagy kinyomtatni az adathordozón található e licencszerződést; vi) Tilos további megkötések hozzávétele ezen felhasználói feltételekhez. Ha a tárgykód vagy a futtatható állomány terjesztése oly módon valósul meg, hogy lehetővé válik valamely kijelölt helyről való letöltése, és ha ugyanezen helyről lehetővé válik a forráskód letöltése is, akkor e cselekmény ugyanúgy a forráskód terjesztésének számít, függetlenül attól, hogy esetleges harmadik személyek számára nem kötelező a tárgykóddal együtt a forráskódot is lemásolni. 3. Jogi fenntartások A Program használata semmilyen jogok formálására nem ad lehetőséget az itt kifejezetten feltüntetettektől eltekintve. Nem jogosult a Program másolására, módosítására, továbblicencelésére vagy terjesztésére a jelen licencszerződésben foglaltakon

kívül. Minden ilyen kísérlet a Program nem jelen licencszerződésbeli keretek között való másolására, módosítására, továbblicencelésére vagy terjesztésére tilos, és ennek hatására az ön e licencszerződésben foglalt minden joga automatikusan visszavonásra kerül, habár olyan harmadik személyek jogai, akik jogai vagy Programja e licencszerződés keretein belül öntől eredeztethetőek, nem kerülnek automatikusan visszavonásra mindaddig, amíg a korlátozásokat betartják. 4. További fenntartások Ha a Program terjesztése és/vagy használata valamely országban bármely okból tilos, a Licencadó hozzáfűzhet konkrét földrajzi terjesztési határokat ezen országok kirekesztése céljából úgy, hogy a terjesztés csak azokban az országokban vagy országok között 220 megengedett, amelyek nincsenek eképpen kivételként megadva. Ilyen esetben jelen licencszerződés az itt felsorolt korlátozásokkal együtt érvényes 5. Korlátozások A

PROGRAMOT AZ „ADOTT ÁLLAPOTBAN”, AZOK ESETLEGES HIBÁIVAL EGYÜTT BIZTOSÍTJUK ÖNNEK MINDENNEMŰ GARANCIA NÉLKÜL. ELZÁRKÓZUNK MINDEN KIFEJEZETT ÉS HALLGATÓLAGOS SZAVATOSSÁGTÓL ÉS GARANCIAVÁLLALÁSTÓL A PROGRAM TEKINTETÉBEN, BELEÉRTVE TÖBBEK KÖZÖTT A MEGBÍZHATÓSÁGRA, BIZONYOS CÉLRA VALÓ ALKALMASSÁGRA, JOGSZERŰSÉGRE, BITORLÁSTÓL VALÓ MENTESSÉGRE VONTAKOZÓ ESETLEGES SZAVATOSSÁGOT ÉS GARANCIÁKAT. A PROGRAM TELJESÍTMÉNYÉVEL ÉS MINŐSÉGÉVEL KAPCSOLATOS ÖSSZES KOCKÁZAT ÖNRE HÁRUL. A PROGRAMMAL KAPCSOLATBAN BÁRMELY OKBÓL ELSZENVEDETT KÁR ESETÉN MINDENNEMŰ TELEPÍTÉSI, JAVÍTÁSI ÉS EGYÉB KÖLTSÉG ÖNRE HÁRUL. AMENNYIBEN A HELYI TÖRVÉNYEK MÁSKÉNT NEM RENDELKEZNEK, EGY ESETLEGES EGYETÉRTŐ ÍRÁSOS NYILATKOZAT NÉLKÜL, A LICENCADÓ VAGY MÁS HARMADIK SZEMÉLY, AKINEK FENTEBB ENGEDÉLYEZETT MÓDOKON LEHETŐSÉGE VAN MÓDOSÍTANI ÉS/VAGY TERJESZTENI A PROGRAMOT, NEM VÁLLAL SEMMILYEN FELELŐSSÉGET A KÖZVETLEN, KÖZVETETT,

KÜLÖNLEGES, VÉLETLENSZERŰ VAGY KÖVETKEZMÉNYES KÁROKÉRT (BELEÉRTVE TÖBBEK KÖZÖTT AZ ADATVESZTÉST, HIBÁS ADATOK ELŐÁLLÍTÁSÁT, ÖN VAGY MÁS HARMADIK SZEMÉLY RÉSZÉRE EGYÉB VESZTESÉG OKOZÁSÁT VAGY AZT, HOGY A PROGRAM NEM MEGFELELŐEN MŰKÖDIK EGYÜTT MÁS PROGRAMOKKAL), MELY A PROGRAM HASZNÁLATÁBÓL VAGY GONDATLANSÁGBÓL ERED, TEKINTET NÉLKÜL ARRA, HOGY A KÁR BEKÖVETKEZTÉNEK LEHETŐSÉGÉRE A LICENCADÓ VAGY MÁS HARMADIK SZEMÉLY FELHÍVTA-E A FIGYELMET VAGY SEM. 6. Általános érvényű rendelkezések Jelen licencszerződés az Ausztráliai Victoria állambeli törvény értelmében készült. Ha jelen licencszerződés bármely része ellentétben áll a hatályos jogszabályokkal, azon részek a kötelezően alkalmazandó jogszabályok által megengedett legnagyobb mértékben alkalmazandók, a licencszerződés más részeinek változatlanul hagyása mellett. 221 10. A CD-melléklet tartalma A mellékelt adathordozón témakörök szerint

csoportosítva megtalálható minden, a programfejlesztéshez szükséges dokumentum. 10.1 Adathordozó főkönyvtár A CD-melléklet főkönyvtárában egyedül ez a dokumentum található, amely a szakdolgozat teljes, forrásprogramokkal is kiegészített verziója. A nyomtatott verzióból terjedelmi okokból kimaradt részek is megtalálhatók ebben a dokumentumban A dokumentum a CD-mellékleten Adobe PDF formátumban található A fájl neve: - Szakdolgozat.pdf A főkönyvtárban további alkönyvtárak is találhatók, név szerint: - Cardlist - GSView - VC6Sample - Egyeb 10.2 A Cardlist alkönyvtár Az alkönyvtárban található meg a Cardlist program forráskódja. A forráskód Microsoft Visual Studio 6 formátumú állományokat tartalmaz, amelyek csak részben kompatibilisek a Visual Studio 7 állományaival. Az alkönyvtár további alkönyvtárakat is tartalmaz, név szerint: res és Release. A res könyvtárban találhatók bizonyos erőforrásfájlok, a

Release könyvtárban pedig a futtatható állomány. Az állományok nevei: - Cardlist.cpp - Cardlist.dsp - Cardlist.dsw - Cardlist.h - Cardlist.rc - CardlistDlg.cpp - CardlistDlg.h - CodeDlg.h - CodeDlg.cpp - extr.bin - FileCodeDlg.cpp - FileCodeDlg.h - ReadMe.txt - resource.h 222 - Scard.cpp - Scard.h - StdAfx.h - StdAfx.cpp - res - Cardlist.ico - Cardlist.rc2 - Release - Cardlist.exe 10.3 A GSView alkönyvtár Az alkönyvtárban az intelligens kártyával kibővített GSView36 program lefordított futtatható állományai találhatók. A forráskódok ezen belül a GSV36-Source alkönyvtárban találhatók meg. Itt közvetlenül az eredeti forráskód található, az általam végzett intelligens kártya kibővítés ezen belül a Scard alkönyvtárban található A forráskód Microsoft Visual Studio 6 formátumú állományokat tartalmaz, amelyek csak részben kompatibilisek a Visual Studio 7 állományaival. Az eredeti, futtatható

állományok egy önkicsomagoló futtatható állományban a GSView alkönyvtár Eredeti alkönyvtárában találhatók. Az állományok nevei: - cdorder.txt - epstool.exe - epstool.htm - extr.bin - gsprint.exe - gsprint.htm - gsview.css - gsview32.exe - gsview32.ico - gsviewde.hlp - gsviewen.hlp - gsviewes.hlp - gsviewfr.hlp - gsviewit.hlp - gsvw32de.dll - gsvw32es.dll - gsvw32fr.dll 223 - gsvw32it.dll - gvwgs32.exe - LICENCE - printer.ini - Readme.htm - regorder.txt - uninstgs.exe - GSV36-Source - cdorder.txt - epstool.zip - FILE ID.DIZ - gsview.css - LICENCE - pstotext.zip - Readme.htm - src.zip - scard - extr.bin - gvcrc.h - gvwin.cpp - gvwin2.rc - gvwinc.mak - gvwinvc.mak - Readme.txt - resource.h - scard.cpp - scard.h - scindlg.cpp - scindlg.h - secure.cpp - secure.h - secure1.rc - s crypt.cpp - s crypt.h - build.bat 224 - de - gvclang.rc - en - gvclang.rc - es - gvclang.rc - fr - gvclang.rc - it - gvclang.rc - Eredeti -

Gs650w32.exe - gsv36w32.exe 10.4 A VC6Sample alkönyvtár Az alkönyvtárban található meg a VC6Sample program forráskódja. A forráskód Microsoft Visual Studio 6 formátumú állományokat tartalmaz, amelyek csak részben kompatibilisek a Visual Studio 7 állományaival Az alkönyvtár további alkönyvtárakat is tartalmaz, név szerint: res és Release. A res könyvtárban találhatók bizonyos erőforrásfájlok, a Release könyvtárban pedig a futtatható állomány Az állományok nevei: - EditDlg.h - EditDlg.cpp - Olvass.el! - ReadMe.txt - resource.h - SCARD.ERR - Scard.cpp - Scard.h - StdAfx.h - StdAfx.cpp - VC6Sample.dsw - VC6Sample.h - VC6Sample.cpp - VC6Sample.rc - VC6Sample.dsp - VC6SampleDlg.h 225 - VC6SampleDlg.cpp - res - VC6Sample.ico - VC6Sample.rc2 - Release - VC6Sample.exe 10.5 Az Egyéb alkönyvtár Az alkönyvtárban találhatóak azok a dokumentációk, melyek szükségesek az intelligens kártyák

programozásához vagy nem kapcsolódnak szigorúan egyik programhoz sem. A dokumentumok oktatási, tanulási célra bárki által szabadon hozzáférhetőek. Az állományok az ScardServer dokumentációját és az ETSI szabványok közül a GSM 0338, GSM 03.40, GSM 0411 és GSM 1111 állományokat tartalmazza Emellett itt szerepelnek a kártyaolvasót aktiváló segédprogramok is. Az állományok nevei: - gsmts 1111v050300p.pdf - gsmts 0338v050300p.pdf - gsmts 0340v050300p.pdf - gsmts 0411v050100p.pdf - scrd214e.pdf - aktiv.bat - Control.exe - TWKDiag.cpl 226 11. Tapasztalatok A szakdolgozat és a hozzá kapcsolódó program elkészítéséhez a legtöbb egyetemi tantárgy ismeretanyaga hozzásegített. Nem is kívánom mindet megemlíteni itt, csak a legjelentősebbeket, amelyek leginkább segítettek kialakítani programozási gondolkodásmódomat Az alapokat Fóthi Ákos: Bevezetés a programozásba szolgáltatta, majd Sike Sándor: Programozási módszertan

tárgyai tökéletesítették ezt, például a keresőalgoritmusok megismerése, lekódolása terén. A szakdolgozat programjainak elkészítése C nyelven történt. A C nyelvű programozási jártasságot teljes egészében az egyetemen szereztem. Az elméleti jártasságot köszönhetem Porkoláb Zoltánnak, aki ezt a Programozási nyelvek 2, majd pedig a Programozási nyelvek sávon a C++ órák keretein belül tanította. Gyakorlati jártasságot is itt szereztem, emellett még Molnár Márknak köszönhetően a Programozási módszertan 2 félévében A programozási nyelv és az algoritmusok ismerete önmagában kevés lett volna, szükséges hozzá, hogy az ember gyakorlatot és módszereket ismerjen a tanult algoritmusok adott programnyelvi környezetbe való átültetéséhez. Ezt Nyékiné Gaizler Judit: Programozási nyelvek című tantárgya biztosította a számomra A szakdolgozat témakörének megismerését nagyrészt Kincses Zoltánnak köszönhetem, aki a

„Bevezetés az intelligens kártyák világába” nevű tantárgyával lopta szívembe az adott témakör szeretetét. Emellett a mindenki által csak Security specinek hívott óráival tanított meg arra, hogy szenteljek kellő figyelmet a biztonság témakörének is. Hogy az optimális rendszergazda gondolkodását egy tőle hallott mondattal jellemezzem: „Tudom, hogy paranoiás vagyok, de vajon elég paranoiás vagyok-e?” A fentieken kívül maga a feladat megvalósítása jelentette számomra a legnagyobb tanulságot. Egy komplex program elkészítése egy mégolyan tökéletes fejlesztőkörnyezetben is, mint a Visual Studio, összetett gondolkodásmódot és újszerű tapasztalatot jelent Az elkészült programok bizonyítják, hogy meg tudtam felelni a vállalt kihívásoknak, s az elkészült program egyben tudásom szintjének és jórészt programozási stílusomnak fokmérője. Másik fontos tanulság, hogy a programot az ember nem, vagy nem csak magának írja.

Mind a program elkészítése során, mind később, a dokumentáció elkészítése során szükség van egy képzelt harmadik személy, egy kívülálló szemszögéből megítélni a dolgokat. Ez helyenként nagy nehézséget jelent, hiszen nem láthatjuk át egymagunk a felhasználók minden csoportját, főleg nehéz kitalálni egy számunkra esetleg logikátlan lépést, melyre a programunknak reagálni kell. Nem véletlen, hogy a nagy programfejlesztő cégek a szoftvert elkészülte után még hónapokig tesztelik Mindezeket megkönnyítik, ha az egyetemen tanultakat ötvözzük az adott feladat megoldásával, ezáltal számos nehézségtől szabadulhatunk meg. 227 12. Köszönetnyilvánítás 1. Szeretnék köszönetet mondani szüleimnek, hogy támogattak tanulmányaim során, valamint tanáraimnak, akik mindent megtettek azért, hogy a szak tudásanyagát maximálisan átadják. Kiemelném közülük témavezetőmet, Kincses Zoltánt, aki egyedülálló

erőfeszítéseket tett a szakon, hogy a „biztonság” és azon belül az „intelligens kártyák” témaköre iránt érdeklődők kíváncsiságát kielégítse, valamint külön köszönetet mondanék neki türelméért és az általam választott ötlet támogatásáért. 2. Szeretném megköszönni a European Telecommunication Standards Institute-nak, hogy oktatási, tanulási célra díjtalanul rendelkezésemre bocsátotta a kért, többszáz euró értékű GSM szabványokat. 3. Köszönetet mondok a Magyar Szabványügyi Hivatalnak, amiért diákigazolvánnyal az épület ingyen látogatható és a szabványok ingyen olvashatók. Csupán azt nem értem, hogy ha a szabványok lemásolását támogatják (biztosítanak tollat, papírt, keresőrendszert stb), akkor a környezetkímélő megoldások (elmenteni floppylemezre) miért tilosak. 4. Köszönetet mondok továbbá Bo Lavare-nak, amiért az általa készített GSM oldallal megadta a kezdő lökést, hiszen mindannyian

hozzá-nem-értőként kezdjük és a súlyos szakszöveget csak az amúgy is szakmabeliek értik. Valamint köszönet az általa kivonatosan közölt ISO 7816-4 szabványért, melyet egyébként csak több ezer Forintnyi euróért tölthettem volna le. 5. Köszönet a Zonenet Development Inc-nek (http://wwwzonedevelopmentcom) amiért megmutatták, hogy egy smartcard programozása nem mindig bonyolult. 6. Valamint köszönet a Towitoko AG-nek, hogy termékeikkel és weboldalaikkal (http://www.towitokode) számos értékes információval szolgáltak szakdolgozatom megírásához. 228 13. Irodalomjegyzék A szakdolgozat elkészülése során az alábbi műveket, weboldalakat használtam fel: 1. GSM 03.38 (ETS 300 628): „Digital cellular telecommunication system (Phase 2); Alphabets and language-specific information” 2. GSM 03.40 (ETS 300 536): „Digital cellular telecommunications system (Phase 2); Technical realization of the Short Message (SMS) Service Point-toPoint

(PP)” 3. GSM 04.11 (ETS 300 559): „Digital cellular telecommunications system (Phase 2); Point to Point (PP) Short Message Service (SMS) support on mobile radio interface” 4. ISO 7816-1 (1987): „Identification cards - Integrated circuit(s) cards with contacts, Part 1: Physical characteristics” 5. ISO 7816-2 (1988): „Identification cards - Integrated circuit(s) cards with contacts, Part 2: Dimensions and locations of the contacts” 6. ISO/IEC 7816-3 (1989): „Identification cards - Integrated circuit(s) cards with contacts, Part 3: Electronic signals and transmission protocols” 7. ScardServer V2.14 Technical Documentation (Release 2001-05-31) 8. Smartcard security information page by Bo Lavare (http://www.geocitiescom/ResearchTriangle/Lab/1578/gsmhtm, http://www.geocitiescom/ResearchTriangle/Lab/1578/smarthtm) 9. TOWITOKO AG - German Technology (http://www.towitokode/deutsch/eng/indexhtm) 10. Zonenet Development Inc. (http://www.zonedevelopmentcom) 11.

Microsoft Developer Network (http://www.microsoftcom) 12. Michael J. Young: Visual C++ 6 Mesteri szinten (1998) 13. Brian W. Kernigham - Dennis M Ritchie: A C programozási nyelv (1988) 14. Bruce Schneier: Intelligens kártyák biztonsági modelljei (1999) 229 14. Szószedet A szakdolgozat számtalan rövidítést, idegen szót, szakkifejezést tartalmaz. Ezek nagy részét azonban csak az adott helyen használom, vagy csupán bemutatás erejéig említem meg. Más szavakat viszont a későbbiekben is felhasználok, azokat a definíciójuk után már ismertnek tételezem fel. Ezekből a szavakból alkottam meg a következő szószedetet, megkönnyítve a dolgozat olvashatóságát adatelem: A legkisebb olyan bithalmaz, amelyre egyértelműen hivatkozni lehet. Általában 1 bájt a mérete. 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. ADM: Administration phase - adminisztrációs fázis Amikor a SIM kártya elkerül a gyártótól, és még mielőtt a felhasználóhoz kerülne, a szolgáltatónál ebben a fázisban található. Ekkor módosíthatóak bizonyos adatelemek a kártyán, melyek a későbbiekben már nem. A kifejezést főként annak jelzésére használják, hogy az adott művelet csak az adminisztrációs fázisban végezhető el. APDU: Application Data Unit Minden egyes Java applet, amit a kártyára letöltünk, egy-egy 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 kap, amely egy adategység, amit a PC küld el a kártyának egy csomagban. API, Win32 API: Application Programming Interface Windows, Java és számos más típusú API létezik. Ez egy olyan interfész, amely két logikai réteg között helyezkedik el, és az

import/export felületek definíciója alkotja. A Win32 API segítségével számos, az operációs rendszer által támogatott funkció érhető el, ugyanakkor ez alacsonyabb szintű hozzáférést jelent, mint amit pl. az MFC biztosít. ATR: Answer to Reset - válasz a „reset”-re Az intelligens kártya működésének legelső lépése. Amikor a kártyát behelyezzük és az olvasó „reset” jelet küld a kártyának, vagy akár egy későbbi „reset” során, a kártya válaszol, a megfelelő protokollok figyelembe vételével. A folyamat során állapítja meg az olvasó a kártya típusát, órajelét stb vagy éppen azt, hogy nem támogatja az adott kártyatípust. Answer-to-Reset fájl: Olyan elementary file, amely az intelligens kártya működési tulajdonságairól tudósít. Ez az adatstruktúra tartalmazza az ATR információkat belső EF: Olyan EF, amelyet a kártya belső működése során tart karban és adatokat tárol benne. CHV: Card holder verification -

kártyabirtokos ellenőrzés Az intelligens kártyák gyakran tartalmaznak olyan adatblokkokat, melyek kényes 230 adatokat tartalmaznak. Ezek hozzáférését jelszóval korlátozzák A jelszó megadásának folyamatát jelenti a CHV A megadandó jelszavakat pedig PIN kódoknak hívjuk ciklikus rekord: Olyan rekordszerkezet, melyben a legutoljára létrehozott rekordbejegyzés az első bejegyzés, az utolsó előtti a második stb. Ha új bejegyzést hozunk létre, akkor minden meglévő bejegyzés sorszáma növekszik, a legnagyobb sorszámú pedig törlődik oly módon, hogy helyére a nála eggyel kisebb sorszámú kerül. CLA: Class of instruction - utasítás osztálya Minden, a GSM SIM kártyák által értelmezett utasítás „CLA INS P1 P2 P3” szerkezetű. Ebből az első paraméter az utasítás osztályát határozza meg Ez azonban a SIM esetében kötött, mindig „A0”. Más intelligens kártyák esetén eltérhet az értéke, sőt, az utasítás paramétereinek

szerkezete is Az azonban nem változhat, hogy az utasítás osztálya szerepel mindig az első helyen. CLK: Clock - órajel Az intelligens kártyák kivezetéseinek egyike. Ezen keresztül biztosítja a terminál a szükséges órajelet a mikrochip számára. Használata opcionális Command: utasítás Az SCARD protokoll használata esetén az intelligens kártyát vezérlő utasítások jellemzése három paraméterrel adható meg: Command, DataIn, DataOut. A Command alkotja a protokollnak megfelelő parancssztringet. command-response pár: Két összetartozó üzenet, mely egy parancsból és az őt követő válaszból áll. CSP: Criptographic Service Providers A CSP egy független szoftvermodul, amely kriptográfiai algoritmusokat és szolgáltatásokat tartalmaz. Segítségével lehetővé válik az alkalmazásfejlesztők számára, hogy autentikációt, kódoló függvényeket és titkosító algoritmusokat adhassanak a Win32alapú alkalmazásaikhoz. A fejlesztők anélkül

használhatják a funkciókat, hogy bármit is tudnának az adott implementációról DataIn: bejövő adatok Az SCARD protokoll használata esetén az intelligens kártyát vezérlő utasítások jellemzése három paraméterrel adható meg: Command, DataIn, DataOut. A DataIn az adott parancssztringnek megfelelő tartalmú, az utasítás paraméterének tekinthető adatblokk. DataOut: kimenő adatok Az SCARD protokoll használata esetén az intelligens kártyát vezérlő utasítások jellemzése három paraméterrel adható meg: Command, DataIn, DataOut. A DataOut a kiadott utasításoknak megfelelően a kártya válaszát tartalmazza. DF: Dedicated file 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 DF név: Karaktersztring, amely egyértelműen azonosítja az adott DF-t a kártyán. DLL: Dinamic link library Olyan futtatható állomány, amelybe bizonyos funkciókat

integráltak. Főleg rendszer- 231 funkciók esetén használatos. Több belépési pontja is lehet, amelyeken át szabadon meghívható a futtatható állomány. Document/View Architecture Support: Olyan programfelépítési elképzelés, melynek során többféle szabványos osztály jön létre egy program megalkotásakor. Ilyen szabványos osztály a View, amely a felhasználói felület kezeléséért, megjelenítéséért felelős, a Document, amely az adatok kezelését és a lemezműveleteket végzi vagy a Mainframe, amely a programra átfogóan jellemző információk tárolását, megadását végzi. EF: elementary file Olyan adatelemek vagy rekordok együttese, amelyek egyazon fájl azonosító alá tartoznak. Nem lehet más fájlok őse elérési út: Fájl azonosítókból konkatenációval előálló sorozat, amely ha az MF-el kezdődik, akkor abszolút elérési útról beszélünk ETSI: European Telecommunications Standars Institute Az európai telekommunikációs

szabványok kidolgozásáért és kezeléséért felelős szervezet. Székhelye Franciaországban található fájl azonosító: Egy 2-bájtos bináris érték, mely egy fájl meghatározására szolgál. file control paraméterek: Egy fájl logikai, strukturális és biztonsági attribútumai. 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 fix méretű rekord: Olyan rekordszerkezet, melynek mérete kezdetektől fogva adott, az nem változtatható meg, szemben a változó méretű rekordszerkezettel. Könnyű implementálhatósága miatt a SIM kártyák ezt használják. GND: földelés Az intelligens kártyák kivezetéseinek egyike. Ezen keresztül biztosítja a terminál a szükséges ellentétes elektromos pólust a mikrochip számára. GSM: Global System for Mobile Olyan mobilkommunikációs rendszer, melynek célja, hogy vezeték nélküli készülékeken bárhol a

világon telefonhívásokat intézhessünk vagy hívásokat fogadhassunk. Ennek megvalósítása érdekében egy szabványos rendszert dolgoztak ki, amit GSMnek hívnak. GUI: Graphical User Interface A grafikus felhasználói felület olyan input/output felület, melynek segítségével felhasználóbarát környezetben, a legkevésbé elvont módon történik az információk bevitele és megjelenítése. A legismertebb ilyen interfész a Windows felhasználói felülete Ez más alkalmazásokból is felhasználható, a könnyű kezelhetőség érdekében IC: Integrated circuits Az integrált áramkörök a modern technológia félvezetőkön alapuló fejlesztése. Segítségével milliárdnyi áramkört zsúfolnak parányi helyre Az intelligens kártyák belseje a „mikrochip” is egy ilyen integrált alkatrész 232 IMSI: International Mobile Subscribing Identifier A SIM kártyákon található olyan egyedi adatblokk, amelyet külön fájlban, PIN kóddal védve tárolnak.

Egyediségét a mobilszolgáltató biztosítja Ennek segítségével lehet a kártyatulajdonost a hálózaton azonosítani INS: Instruction code - utasításkód Minden, a GSM SIM kártyák által értelmezett utasítás „CLA INS P1 P2 P3” szerkezetű. Ebből a második paraméter az utasítás osztályon belüli kódját határozza meg Más intelligens kártyák esetén eltérhet az utasítás paramétereinek szerkezete. Az azonban nem változhat, hogy az utasításkód szerepel mindig a második helyen. intelligens kártya: Az intelligens kártyákat nap mint nap használjuk, mint egyes bank-, telefon-, mobiltelefon-kártyák (SIM), diákigazolvány, vagy a számtalan kereskedelmi cég „pontgyűjtés”-re használható kártyái. 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, így egy apró számítógépnek is tekinthetők. A 80-as évektől létezik a technológia, hogy minden funkciót egyetlen mikrochipben helyezzenek el. I/O: Input/Output Az intelligens kártyák kivezetéseinek egyike. A kártya belsejében található IC soros átvitelre alkalmas Input/Output csatlakozása ISO/IEC 7816: Átfogó szabvány az intelligens kártyákról A GSM SIM kártyán egy, az ISO és az ETSI szabványok által specifikált feltételeknek megfelelő alkalmazás található. A fizikai felépítést az ISO/IEC 7816 part 1-3 (Asynchronous smartcard information) szabványok definiálják. A külvilággal való kommunikáció számára az APDU-kat az ISO/IEC 7816-4 (Interindustry commands for interchange) definiálja. Java Card API: A GSM SIM kártya tulajdonképpen egy olyan Java alapú

processzorkártya. A szinte mindenhol használható Java nyelvet azért alkalmazták, hiszen a nyelv platformfüggetlen, másrészt egy Java applet kellően kicsi. A Java nyelvű rendszer a Java Card API interfészen keresztül programozható. Objektum orientált szemléletet követ, minden egyes applet, amit a kártyára letöltünk, egy-egy 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 kap. külső EF: Olyan EF, amelyet nem a kártya tart karban. lineáris rekord: Olyan rekordszerkezet, melyben a legkorábban létrehozott rekordbejegyzés az első bejegyzés, a legkésőbbi pedig az utolsó. Ha új bejegyzést hozunk létre, akkor meg kell adni, hogy mely azonosítóra tesszük, az azonosítók folyamatosan növekednek. MDI: Multi Document Interface - Többdokumentumos alkalmazás Olyan alkalmazás, melyben több dokumentum vagy állomány is lehet egyidejűleg

nyitva. Ilyen például a Microsoft Word Ha új dokumentumot nyitunk, az előző nem záródik be. 233 ME: Mobile Equipment - mobiltelefon A mobiltelefonos kommunikációban a felhasználó tulajdonában lévő hardvereszközökből a SIM kártyától eltekintve minden más az ME-nek tekinthető. memóriakártya: Alapvetően kétféle típusú intelligens kártyát különböztethetünk meg, ezek egyike a csak adattárolásra alkalmas memóriakártya. A kártya csak memóriaegységet tartalmaz MF: Master File Olyan DF az intelligens kártyán, amely kiemelt jelentőséggel bír, ez ugyanis kötelezően egyedi, a fájlrendszer gyökerét alkotja, minden más fájlnak őse. MFC: Microsoft Foundation Classes A Microsoft Visual C++ számos különböző módozatot kínál fel Windows GUI programok írására. 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 és még sok más egyebet is. Az MFC a programozási munkánkat meglehetősen könynyebbé teheti MO: Mobile Originated (Message) Azokra az üzenetekre vagy hívásokra mondjuk, melyek a mobiltelefontól az adóközpont felé irányulnak. (ME MS) MS: Mobile Station A mobiltelefonos kommunikációban a szolgáltató tulajdonában lévő hardvereszköz, amely kommunikációt végez a mobiltelefonokkal. Gyakorlatilag az adótorony és a benne található rádiókommunikációs egységek, szoftverek. MSDN: Microsoft Developer Network A Visual Studio részeként a számítógépünkre települ, emellett az Interneten is elérhető olyan programfejlesztést segítő dokumentáció, amely példaprogramokkal, referenciákkal nélkülözhetetlen a Win32 alapú alkalmazások fejlesztéséhez. MT: Mobile Terminated (Message) Azokra az üzenetekre vagy hívásokra mondjuk, melyek az adóközponttól a mobiltelefon felé

irányulnak. (MS ME) P1: Parameter 1 Minden, a GSM SIM kártyák által értelmezett utasítás „CLA INS P1 P2 P3” szerkezetű. Ebből a harmadik paraméter az utasítás első paraméterét határozza meg Más intelligens kártyák esetén eltérhet az utasítás paramétereinek szerkezete. P2: Parameter 2 Minden, a GSM SIM kártyák által értelmezett utasítás „CLA INS P1 P2 P3” szerkezetű. Ebből a negyedik paraméter az utasítás második paraméterét határozza meg Más intelligens kártyák esetén eltérhet az utasítás paramétereinek szerkezete. P3: Parameter 3 Minden, a GSM SIM kártyák által értelmezett utasítás „CLA INS P1 P2 P3” szerkezetű. Ebből az utolsó paraméter az utasításhoz tartozó adatblokkhoz tartozik Más intelligens kártyák esetén négy féle szerkezete lehet az adatblokknak, SIM kártya esetén viszont a P3 vagy a küldött adat vagy az elvárt adat hosszát jelzi. 234 PIN: Personal Identifier Number Az intelligens

kártyák gyakran tartalmaznak olyan adatblokkokat, melyek kényes adatokat tartalmaznak. Ezek hozzáférését jelszóval korlátozzák A megadandó jelszavakat PIN kódoknak hívjuk PIN1, PIN2: Az intelligens kártyák többféle hozzáférési szintet engedélyezhetnek, vagy akár egymást kizáró, de egyébként egyszintű jogosultsági rendszerrel is rendelkezhetnek. Ennek megfelelően több PIN kód alkalmazása szükséges. A SIM kártyák két ilyen kódot használnak. PLMN: Public Land Mobile Network - Nyilvános földi mobiltelefonos hálózat A kifejezés speciális jelentésén túl (lásd ETSI GSM 11.11 szabványt) nagyjából úgy foglalható össze, hogy egy adott mobilszolgáltató összes mobiltelefonos berendezése (adótornyok stb.) egy PLMN-nek felel meg processzorkártya: Alapvetően kétféle típusú intelligens kártyát különböztethetünk meg, ezek egyike az önálló számítási és feldolgozási kapacitással is rendelkező processzorkártya. A kártya

nemcsak memóriaegységet, hanem mellette processzort is tartalmaz. Lehet programozni vagy felhasználói programok futtatására is alkalmazni. RC2 block cipher: Olyan kódoló algoritmus, amely az RC2 nevű 64-bites szimmetrikus blokk-kódolást használja. Az algoritmus adott méretű blokkokon végez műveletet, ezért ha a kódolandó szöveg nem osztható fel pontosan ilyen blokkokra, az algoritmus azt kiegészíti véletlenszámokkal. Az algoritmust az RSA Data Security, Inc fejlesztette ki, forráskódja, működési módja nem nyilvános RC4 stream cipher: Olyan kódoló algoritmus, amely az RC4 nevű szimmetrikus adatfolyam-kódolást használja. Az algoritmus változó méretű adatfolyamokon végez műveletet, ezért a kódolás során nem változik az adatfolyam mérete. Az algoritmust az RSA Data Security, Inc. fejlesztette ki, forráskódja, működési módja nem nyilvános rekord EF: Az intelligens kártyán található fájlokat szerkezetük szerint transzparens

struktúrájúakra és rekord struktúrájúakra csoportosíthatjuk. A 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 EF-en belül. rekord szám: Szekvenciálisan minden rekordhoz tartozó egyedi azonosító, amely egy EF-en belül egyértelműen azonosítja. RFU: Reserved for future use - Későbbi fejlesztésekre fenntartva Bizonyos adatmezők vagy funkciók jelen pillanatban még nincsenek használatba véve az adott eszközön belül. A széles körű felhasználási lehetőségek érdekében, hogy a technológia ne avuljon el a gyors fejlődés során, a tervezők előrelátóan „helyeket hagynak” a későbbi fejlesztésekhez. Így például egy újabb érintkező a mikrochiphez jelen pillanatban lehet RFU, de ha a chip

következő verziója új szolgáltatást szeretne 235 nyújtani, akkor nem kell lecserélni az összes eddigi kártyaolvasó rendszert az új láb miatt. RST: Reset Az intelligens kártyák kivezetéseinek egyike. Ezen keresztül küldi a terminál a szükséges esetben a „reset” jelet a mikrochip számára. Vagy önmagában használatos (a jel az olvasótól érkezik) vagy egy belső „reset”-vezérlő áramkörrel kombinálva (kártyafüggő). Ha a belső „reset” implementált, akkor a kártya folyamatos VCC feszültséget igényel SAM: Secure Access Module - Biztonsági hozzáférési modul Az ún. kétkártyás rendszerek, mint pl az új diákigazolvány, esetén a GSM SIM kártyáktól eltérően minden kártyaművelethez az adott kártyán kívül szükség van egy SAM-re. Ez nagyban megnöveli a biztonságot SCARD: Az ScardServer szolgáltatáshoz kapcsolódó interfész. A kliensoldali alkalmazásokban való implementációja rendkívül egyszerű, egyetlen

DLL-fü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 ScardServer: Számos különböző cég számos saját szabványt fejlesztett ki a saját kártyáik kezelésére. Az ScardServer is egy ilyen, a Towitoko AG által kidolgozott hozzáférési szabvány, kifejlesztésének célja az volt, hogy 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 operációs rendszereken. Az alkalmazások többféle protokollt felhasználva kommunikálhatnak a szerverrel SDI: Single Document Interface - Egydokumentumos alkalmazás Olyan alkalmazás, melyben csupán egyetlen dokumentum vagy állomány lehet egyidejűleg nyitva. Ilyen például a Microsoft Paintbrush Ha új dokumentumot nyitunk, az előző azonnal bezáródik. session: Az a két

„reset” (RST) közötti időtartam, amíg az intelligens kártya tartósan feszültség alatt van. A session kezdete, amikor a felhasználó behelyezi a kártyáját az olvasóegységbe és ha szükséges, bekapcsolja azt (pl. mobiltelefon), minek hatására az olvasó végrehajtja a kártya-”reset”-et. A session vége, amikor a felhasználó kikapcsolja az olvasót, vagy eltávolítja a kártyát, és a kártya ezáltal áramtalanításra kerül Szintén a session végét eredményezi, egyúttal egy újabb session kezdetét is, ha a kártya mindvégig feszültség alatt marad, de az olvasó egy új „reset” jelet küld neki. SIM: Subscriber Identity Module - Felhasználói azonosító modul A mobiltelefonos kommunikációban a felhasználó tulajdonában lévő hardvereszközök speciális része. A SIM tulajdonképpen egy Java alapú intelligens processzorkártya, melyen speciális, az ETSI szabványok által definiált alkalmazások találhatók SM: Short Message - Rövid

szöveges üzenet A mobiltelefonok kommunikációja különböző logikai szintekre bontható fel. A kommunikáció egyetlen alkalmazási módja csupán a „rövid szöveges üzenet” szolgáltatás. Az SM jelenleg maximum 160 karakter hosszú lehet, bár a szabvány és a 236 SIM kártyák már támogatják jóval hosszabb üzenetek írását is. Eredetileg az adótornyok és más berendezések kommunikációjának céljából jött létre smartcard: „ügyes kártya” Az intelligens kártyák angol neve, bár gyakran találkozni vele magyar szövegben is. SMS: Short Message Service - Rövid szöveges üzenet szolgáltatás 1. jelentése: Short Message - Rövid szöveges üzenet (lásd SM) 2. jelentése: Az SM küldésének lehetősége, maga a szolgáltatás és megvalósítása Az SM szolgáltatás üzenetek továbbítását teszi lehetővé több GSM PLMN Mobile Station (MS) között a Service Centre (SC) segítségével. SW1: Status Word 1 Minden, a GSM SIM kártyák

által értelmezett utasítás „CLA INS P1 P2 P3” szerkezetű. Ugyanakkor minden ilyen utasításra válaszként egy „Adatblokk SW1 SW2” szerkezetű karaktersorozattal válaszolnak. Az SW1 egy bájt méretű, és SW1=$6x vagy $9x, kivéve $60. Az SW1-SW2 együtt 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 SW2: Status Word 2 Minden, a GSM SIM kártyák által értelmezett utasítás „CLA INS P1 P2 P3” szerkezetű. Ugyanakkor minden ilyen utasításra válaszként egy „Adatblokk SW1 SW2” szerkezetű karaktersorozattal válaszolnak. Az SW2 egy bájt méretű és értéke bármi lehet. Az SW1-SW2 együtt 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. szülő file (ős): Olyan DF, amely közvetlenül az adott fájl felett áll a hierarchiában. transzparens EF: Az intelligens kártyán található fájlokat szerkezetük szerint

transzparens struktúrájúakra és rekord struktúrájúakra csoportosíthatjuk. A transzparens szerkezet szekvenciális adatot tartalmaz, a különböző adatbájtokra az offsetcímükkel hivatkozhatunk változó méretű rekord: Olyan rekordszerkezet, melynek mérete nem kezdetektől fogva adott, az változhat a működés során, szemben a fix méretű rekordszerkezettel. Nehezen implementálhatósága miatt a SIM kártyák nem használják. VCC: Üzemfeszültség Az intelligens kártyák kivezetéseinek egyike. Ezen keresztül biztosítja a terminál a szükséges feszültséget a mikrochip számára. VPP: Programozó feszültség Az intelligens kártyák kivezetésének egyike. Ezen keresztül biztosítja a terminál a szükséges programozó feszültséget a mikrochip számára. Használata opcionális WYSIWYG: What you see is what you get - „Azt kapod, amit látsz” Olyan programozási, de főként felhasználói felület definiálása során használatos módszer, melynek

során különböző grafikai elemeket egérrel a kívánt helyre húzva kapjuk meg a működő programmodult, felhasználói interfészt. 237