diff --git a/.travis.yml b/.travis.yml
index 980ea274..d43987f0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -82,15 +82,6 @@ before_script:
./configure OPENSC_LIBS="-L$PREFIX/lib -lopensc" || cat config.log;
fi
-addons:
- coverity_scan:
- project:
- name: "frankmorgner/vsmartcard"
- description: "Umbrella project for various projects concerned with the emulation of different types of smart card readers or smart cards themselves"
- notification_email: frankmorgner@gmail.com
- build_command: make -C $TRAVIS_BUILD_DIR/virtualsmartcard -C $TRAVIS_BUILD_DIR/ccid -C $TRAVIS_BUILD_DIR/pcsc-relay
- branch_pattern: master
-
script:
# Build virtualsmartcard
- make -C $TRAVIS_BUILD_DIR/virtualsmartcard
diff --git a/virtualsmartcard/README.md b/virtualsmartcard/README.md
index 006c2e24..1874aac0 100644
--- a/virtualsmartcard/README.md
+++ b/virtualsmartcard/README.md
@@ -8,6 +8,7 @@ Currently the Virtual Smart Card supports the following types of smart cards:
(PACE, TA, CA)
- Electronic passport (ePass/MRTD) with support for BAC
- Cryptoflex smart card (incomplete)
+- Belgian electronic ID card (WIP, this fork)
The vpcd is a smart card reader driver for [PCSC-Lite](http://pcsclite.alioth.debian.org/) and the windows smart
card service. It allows smart card applications to access the vpicc through
diff --git a/virtualsmartcard/belpic-example-data/README.md b/virtualsmartcard/belpic-example-data/README.md
new file mode 100644
index 00000000..c1ebc9ef
--- /dev/null
+++ b/virtualsmartcard/belpic-example-data/README.md
@@ -0,0 +1,3 @@
+The .xml file in this directory was generated by [the scripts in the
+eid-test-cards project](https://github.com/Fedict/eid-test-cards). We'll
+make this look better at some point in the future, but not now.
diff --git a/virtualsmartcard/belpic-example-data/belpic.xml b/virtualsmartcard/belpic-example-data/belpic.xml
new file mode 100644
index 00000000..d621530d
--- /dev/null
+++ b/virtualsmartcard/belpic-example-data/belpic.xml
@@ -0,0 +1,82 @@
+
+
+beid
+1
+myfriendlyname
+534C494E336600296CFF278E5519202E
+534C4790432100003077FEAA12925086
+F336012201170003002101
+3B9813400AA503010101AD1311
+
+3F002F00
+61234F0CA000000177504B43532D3135500642454C50494351043F00DF0073050603603802
+
+
+3F00DF005031
+A00A300804063F00DF005035A40A300804063F00DF005037A80A300804063F00DF005034
+
+
+3F00DF005032
+30270201000410534C494E336600296CFF278E5519202E800642454C504943030204309E0403020000
+
+
+3F00DF005034
+3033300F0C0942617369632050494E030206C03003040101A11B30190302020C0A01000201040201088001010401FF300404023F00
+
+
+3F00DF005035
+303A30170C0E41757468656E7469636174696F6E030206C0040101300F04010203020520030203B802020082A10E300C300604043F00DF0002020800303930150C095369676E6174757265030206C004010102010130100401030303060040030203B802020083A10E300C300604043F00DF0002020800
+
+
+3F00DF005037
+302C30170C0E41757468656E7469636174696F6E030206C00401013003040102A10C300A300804063F00DF005038302730120C095369676E6174757265030206C00401013003040103A10C300A300804063F00DF0050393023300B0C024341030206C004010130060401040101FFA10C300A300804063F00DF00503A3025300D0C04526F6F74030206C004010130060401060101FFA10C300A300804063F00DF00503B
+
+
+3F00DF005038
+3082053A30820322A003020102020102300D06092A864886F70D01010B05003031310B30090603550406130242453122302006035504030C1941636D652C20496E6320496E7465726D656469617465204341301E170D3136303732373132323035315A170D3236303732373132323035315A3072310B30090603550406130242453129302706035504031620576F757465722056657268656C7374202841757468656E7469636174696F6E293111300F0603550404130856657268656C7374310F300D060355042A1306576F75746572311430120603550405130B373830353036303939333630820122300D06092A864886F70D01010105000382010F003082010A02820101009367852537831DBFE04BC2BB17242449F8A0E116B5251EF8A4D0FD88893E555DA7AB278E5F203506B88AC50AD5DDA3212FFE6141A0D3E3BEC0344C17515313187D76DBD3C67AF487AF0856CCD894310576C01E6F411560CF71C165432365BD4EBD718456213AF216042339633CD6953403DC1939025325CED854B099B85DCA44C298B6EF4A83E403C3F74001C2C1F4A89F68C4C0C6AA03B41B895B5801727D4DA8C3EF6262BD07F4F2A5442807631109B77E29E1F204B2BEEF0FF0EAD05E99DA05A3BAA5821041DB7056D9786DB3F20F7B732D3ACF7E6CE3EB9A0688D14D40AC1363FC3B8524BBABD38F624D525667F1A9BDA600862E4CAB1D26221D9E0BA21F0203010001A382011A30820116301F0603551D230418301680145E9D7128B78D690D537A036367B4566199DF726F305C06082B060105050701010450304E302806082B06010505073002861C687474703A2F2F6C6F63616C686F73742F63612F726F6F742E637274302206082B060105050730018616687474703A2F2F6C6F63616C686F73743A383838382F30440603551D20043D303B3039060760380A01010202302E302C06082B060105050702011620687474703A2F2F7265706F7369746F72792E6569642E62656C6769756D2E6265302C0603551D1F042530233021A01FA01D861B687474703A2F2F6C6F63616C686F73742F63726C2F63612E63726C300E0603551D0F0101FF040403020780301106096086480186F84201010404030205A0300D06092A864886F70D01010B050003820201005DFBB612B00436D9204A57449750C27D05E6C4931C9680CEBC0D6C2B791664C54774919ECB4A407A93627B711ACC64FE69406F74B55EA2C62B9B88DF41CE0FE11A875ED9F2E82047D1F0AA2F82F685EC19213327B959DF376276C9B05171FD8E07172B559625A6583ECE2E66825A7F84FF0FFC2C4A3C624E100D4B7F2AFBE7CB5A00904D20405FF8E01F867089EFAA2A2595A2EBB21FE7E40DA6C8F080B9493D26C0465FBCE6FD1A19E949118364FCF4BBE4E726C53BFCD55C6E7DA7A5DCDED9320253A49F485960582D85A08134AF48F99B1BCD5FB3DB33630E0F56A883D9AB41A5E5BB619A1A28FAA5C34AF0EF4E9271AEAE865394A8B308E0A364BB1018F0FE6A94947890ECDB8E5BE4FF9891168CC2BF2A7CAE8DC8F145981FA36A0A8A38E06E52C1CF483C21B7A1BDC1F96DC5650E34A317C9CDB5C0D7A2689BCED768B3A75221EE71FBED0F86A264500B2ACC4597EFC5DE4A481A583787BC00B3449368667455C0BD495DFF7C1B8A349B251583519256D719CF12018B964B15F08334CCDF1CC70CD74D87647D8098DFB2988BC654B1D6FB17BA336B25D8EEE8A2DFE4F4618F74203E4125463F301894FE49C7437522D8587D71CCDC39CD491E0C850EB7DE80505CC7006508FDC2A51E89DC159821E174716E36110240C5D3433132D53F67AE34CA7A4323EECB0EDCC766371778E9A9C9B1D2DD6E8C35FFB4592B620BB6
+
+
+3F00DF005039
+3082054F30820337A003020102020101300D06092A864886F70D01010B05003031310B30090603550406130242453122302006035504030C1941636D652C20496E6320496E7465726D656469617465204341301E170D3136303732373132323035315A170D3236303732373132323035315A306D310B3009060355040613024245312430220603550403161B576F757465722056657268656C737420285369676E6174757265293111300F0603550404130856657268656C7374310F300D060355042A1306576F75746572311430120603550405130B373830353036303939333630820122300D06092A864886F70D01010105000382010F003082010A0282010100C1376C76A5FBB9BD070A81BAB947D144471EE26BAC347FF55E2C9A292F5E5CE24B22163D7CE1812D625EA2BA16444ABC43B693DCF4E4E1AA615BAD689E130AE424508A8A9B7339F535138D16A70BA81255F8124C7918903D4B97856D702C8144B4BACEA425B749264B34565CC8F920F78DEA9CFCA5A4F812522663D2404609E68E41904A08548BED4210D950E83CDD5995E30171ACA2AC645A7FA67A7445DED5502A4036FBEAC66B249FEB2B337EBF5D56BC96A195A690E735510CE0D036DF7ECB86A8FF2300FB0E8D2D585D3C9F34F26FBB477077699D4369C97E22F9E6AF8897398168CFE84F06C130F460EB6DB2DADF28D6CB09539AFEC347E7D15AF725D50203010001A382013430820130301F0603551D230418301680145E9D7128B78D690D537A036367B4566199DF726F305C06082B060105050701010450304E302806082B06010505073002861C687474703A2F2F6C6F63616C686F73742F63612F726F6F742E637274302206082B060105050730018616687474703A2F2F6C6F63616C686F73743A383838382F30440603551D20043D303B3039060760380A01010201302E302C06082B060105050702011620687474703A2F2F7265706F7369746F72792E6569642E62656C6769756D2E6265302C0603551D1F042530233021A01FA01D861B687474703A2F2F6C6F63616C686F73742F63726C2F63612E63726C300E0603551D0F0101FF040403020640301106096086480186F8420101040403020520301806082B06010505070103040C300A3008060604008E460101300D06092A864886F70D01010B05000382020100831B92FD2BFFF504BD7BC3B131D79AAFC86F9745B5CDD00285576D8858828BF239D4E082E5A1CFF3ED890DC19F4DD6D9B284890691A3C3DBAECE8DF87634DB6639B0B9789F0C67E3FAE130AB42F4370583B70BA4F422CB541EB0216360385F3F935FE00A36B3135318EFEB26D807ADBEC71AC62A35B03772FFE0EDB0E90B537460CC0A58C4A1D42D78DF57A3009DC7AE9DD87A6CEEBAE86E1B0F64A2D28AFA18CABD9F7D7923508B2A3DF50CEB186BB5B695012F1A3DD7D760173180BABDF19AB054FFCEC061C82D0F01E1FB9649625F4E28FE00E836E775782925A53C3378104AFCDB404AA11C90AE35C7D9A2A16BEE2E7B33303CA1F2D18919DAC3D05015484774B403F2CC0D4A6FAC4354A6320504DAB3138E396A7012332B563E80BA5BFEE3A91EE6A5D6AE0412F01AC33C0198EBCADDFA8DE072F9D67CEAA00D411B6855C1D2605437CCD0607254AE6ABE5913D966748F6EAABB6F7003ADBFA4AAA6DE1015FEAAB9E01B6773FCF9DD66B738EBCCD47F77D51F5FB5F0F0449AE3B674D8C756A5763A85D5C099E543E1F0871335C3F4A409A16A66869D60D3AB5C7D1D7BB9D857CAD564FA34CDE7400D0F9086A4EACCDD08F246101A2A60711D352D4D1BD12B63984C0226ED16FA6FC9BB20623FF2E1434FC6C26C30CA526B32D54AE983A135FE149603DB486D82583A97C68D5DB9ABB1A018511ADBBB85CE8EF603F6B383
+
+
+3F00DF00503A
+308205C9308203B1A003020102020102300D06092A864886F70D01010B0500302F310B30090603550406130242453120301E06035504030C1741636D652C20496E6320654944205465737420526F6F74301E170D3136303732373038353630385A170D3238303732373038353630385A3031310B30090603550406130242453122302006035504030C1941636D652C20496E6320496E7465726D65646961746520434130820222300D06092A864886F70D01010105000382020F003082020A0282020100C873CD4F1AF071C4EB47A344DF775B56F3BE33117F8D7185128E91A32115F6FAFAF0C0B5A2B9E4BA9AB1D264F1E213810F4E13D57A93C8DFA249406A6EF8C857CD905C75D06B38FD517E250CC4E9D653AD1AF55B7E15C5D7632D27DA64F3D4988D1F4B1F5B959D4C2ED0B79F5D1A4A28A346109A895EE69E687BBEF0EDB082835CC6AE0A3EF4026ADA8D6EF3FFF62858235C1C6193CCDF71A1DE9EFECC725B93C577413287B01DA2345016FB1211C7E284E4613DAE781A96D68E27FBDE6DE165D5EC5AF7D0C21DA6EB6636F7EFB279AAD9559BC081915AB245BB69BFB7B7B2EFCB0991E0F3EA1277A4910E8A7922C4BA4F5575B32B913363E19D1EFD5ED0DB4818AEBC1662C28E55323615F62DE16D7DF0628FABBE81CC5F5C50CF4816430F9A966DF412B2CAE12F10A72605E151B87CD2EFCD5FBBB227146A53336C0545D2E498EE83824A2FFC83669D592362FFD911F3FED62F94C9BE45A894216CC2A214F8C377E2E82682813770221DFEC6133E3E69C11F91217508B0F1C171F67E97D3A41AB01C9F0640034AABA7AE37DB2BE1C40FB824AF9A814667F25E020DC5C02B011E3E0AD6E4CA0CC546889A5825E7B04BC7A39DA1316669FA9089A4477561DC3C5C1355693DDEB450EB2BEE0E2C1E2116B6224F9324B2AB6609B5D20724B50C11116DBCDB12FDDA629A991CB129BFF6724A064AED39E34A62C5CE326D63AD19E70203010001A381ED3081EA300E0603551D0F0101FF04040302010630120603551D130101FF040830060101FF02010030430603551D20043C303A3038060660380A010102302E302C06082B060105050702011620687474703A2F2F7265706F7369746F72792E6569642E62656C6769756D2E6265301D0603551D0E041604145E9D7128B78D690D537A036367B4566199DF726F302C0603551D1F042530233021A01FA01D861B687474703A2F2F6C6F63616C686F73742F63726C2F63612E63726C301106096086480186F8420101040403020007301F0603551D230418301680145BC5455E692614597D3F8CD0602276373E71B1CE300D06092A864886F70D01010B050003820201006F78C085841F2744C01F582654193EEA5425FEC3FB09FA9FE85E04D96C2EDC4E38C7DD73B48FC5A7B3F6A0350017C74129AE2A5BD1D317E40A49BE21D5EBD2B9798397BEA39681BAF05EDCFCE09898D490EB113D4945CF17E38FA2E1D4F7EB318E21BB63D9EAC114FB560B149E8EDA82A964517203250B00D9966D4FA70247258265A093194A0B19F2D6C980744B38DA46DD66B3F3077E4A32E912934B4B2C798E5AF6F33337CD2159E07B5FD5A8FBEFECA6BC8E1F1A30CF546C8E10DFFD90C9A98631637CF5D1B1CB82457C7BE9DEF55CAFB0484CE9298C5DCBAA1B67D06FE25BC81575B9EBB55BDAD50E5873DD43F40DD0A984AFECE9CD5F48ACB2A28F40A8A8A2ABEF9C6813BADD7CD96C2653580A781A337D5F2179AC041B3DC42072B557A0F546ADF6B67F8E17E678D3B4E9D4DE39D4FF5A9762FC27337ACB897C41C1522CDC34C9C0B5700FBFA0A945A17AA35F8377CB8C70B036DCD9D07944077E337D38E01B77AE15B229E561ACF60C74B5B03E5B71ECFADAA0D4A30EAF9102736C24B2E0CF80A8C9355D58FD032C15A2971F7B1EA57CF55E766D92972451936152826DD363B567B20437810B1136D8B9F8D2FE791D6C9558257CA9396403E89B1AE92B6C58F74A36B65763EBC7A72B0DE3368BF146BFA9481E5AD2833D184211FAF11C665925EF48C75C5D0ED980EBEC5D92552D1B1E8220E5B4AACE9F77127109BC
+
+
+3F00DF00503B
+3082059D30820385A003020102020900C8BA1AB52E6F1D22300D06092A864886F70D01010B0500302F310B30090603550406130242453120301E06035504030C1741636D652C20496E6320654944205465737420526F6F74301E170D3136303732373038353630375A170D3331303732373038353630375A302F310B30090603550406130242453120301E06035504030C1741636D652C20496E6320654944205465737420526F6F7430820222300D06092A864886F70D01010105000382020F003082020A02820201009FB9137A4650090166906CE38C7A78773AA508D7B4937759D73673E4BFAAE2427BCAE38405761FFB214BE5AA0A2AA57827D4F7F1394E6047FA728F14F44D557878D32C9E8E6AF0F460566E38BC1A207A58E115FCC6035B3F7870A1DD07368490401B3485B7391DFC26F11B9C26432F2F5350CB7AD02D54AD7E9F67738E4ECC39442B53FDA5DEF8A24188E1531E560BC779041165AD46AACEAC10A66504AED94C5865798920CB4EC6AD67284967031A8E08ECFE7DADD0053AA2665BFC32C9130B00CB2703AA7D49DE792EC946F5BDB310ADF5C43BE5DDC493E3AF0DF2B9AA9F75D645F47DCC9D201D0C382AF2670446AE1CC319C558D83C84C5484B5948AE771103535043ACEB20CE71280058E89B08F0212F6D307FBB97CBE3F516390C8A4CA8D505E8A09F9B9B9D2A133DDC0A1DF112D554D8EE7B6FFB8D09DF8C89D03D1C81221E4AA4B4F86F233318E9EFEE85A9E2F3336B622766E5F30994615E0D2574754576F7A8E91709202F80D3C8A591E4A8B9CDDD4D43D86163F150B0B0C8C48F6474DF2084ADA22858B63A8BBF770D4D8177B49DB16968BEC42D9398F021FA179E11A7D0BC28D851EC995E0760A2027FA28F31FAD195E584FC4379E931BB3E32C611908740EB6B6A5A45A36262E572648536CF18C7D034573670D5A253AF3510C787E78258C4CFB25247D01FD4F1DDD069CADC5C6EB49658FF12D9C9E3AA77D7F30203010001A381BB3081B8300E0603551D0F0101FF040403020106300F0603551D130101FF040530030101FF30420603551D20043B30393037060560380A0101302E302C06082B060105050702011620687474703A2F2F7265706F7369746F72792E6569642E62656C6769756D2E6265301D0603551D0E041604145BC5455E692614597D3F8CD0602276373E71B1CE301106096086480186F8420101040403020007301F0603551D230418301680145BC5455E692614597D3F8CD0602276373E71B1CE300D06092A864886F70D01010B050003820201009006A7587713B7496FEADA39D860ABE1C2284E4164469DBCF73252B874DC1B048451F07EA233D3D49EB7AF94107B380C98745E7C306DDCF944966609561EB3F65C9B08DF212F78BFDBCAD3B21CD64D0BE0A70608B9F4F21912B87F8BDDCF6454B9ED82FF7993FAE1AC5F87F156FD229CED6234B5E077A6E3D816EB19EBA3BDCFF89DA9A065A06BC0C5170B7BEAD5FFD6878298DBEAF036AF63C509E430FE99A757D26EECFDDD747E003DA998619EE7467E9978E999BE0817D8B772A72ACCCDE546DB94AE45D1C3CBA2C1D6A7F1E8A39FDAC82ABF71C2C397934E1BA4A380897C2BC7C9144B88367A3C2D0C5ED07B20E0BA43A0CAD6DB489D41C83EDD95BD2E170912FEAC7A0EAA09597A27B1D70CDD5EEFA7523D23DFFF76B7423C405B9902744B3399DA2DE7E178514328A3688156F9603C202868BFDFE6D87E97897AC49973FBDC619F1A6525D5A3A827F6F744C82DE46547F34E8EA497B255A4AA5CF1AF1B27530830DB6B8EAE692B8ABFADB592AC6D2F3069F4DA201412412FC76FEB8F839485CDBAA43B56EFAE55B9FD808FD686D84EF1D11CC5810A57DBA3BDE17C05AA6E7F7AAAE37DF87A676C8F3F5D0E8032FC987EFC4D4B5745EDD83527D582973A4D36E84A4FD88FC23CA215E7E4C880762D0D215BC741F7BF92FEA55169791A225F2CE830AE23F9896ABF7141E31C481FD36FFF7CDFD2D59DF5D0EC86E15F3D13
+
+
+3F00DF00503C
+308204B63082029EA003020102020101300D06092A864886F70D01010B0500302F310B30090603550406130242453120301E06035504030C1741636D652C20496E6320654944205465737420526F6F74301E170D3136303732373038353630375A170D3238303732373038353630375A3038310B300906035504061302424531123010060355040A0C0941636D652C20496E633115301306035504030C0C65494420746573742052524E30820122300D06092A864886F70D01010105000382010F003082010A0282010100B8E713EFF26C1F419C2BE14D190DE1FAB265A121C919C17E75380F460B02AC1A89166F8C407883D36BA434C4F22BCBBA4DF68DA0E6DD3C93C4F4225E41952BA32F978451F5A6EE809BE594B6B4F761D509EF391F3013EB99F698A2CDBE485EED07CACE1C716DE570F654A918C07B60A11265DD0AF6104A17143990564A93FC5DB0201DF5BBB9EA4C215898F5733CC25B832F35983CD2775B3FB52179FFE1D8DCCB9CC8A5565646CF5FB38222B43A4EB5135B144730479CA884606DF2A0FA515831A0668C3152ACC5BF1EAB035C6D0D9ACDBB178954FBC0B8BEBADF56C2137A9B7A70EDADC85CE51931591D61A7602FAB4BED1070498A872E76F430493A407B050203010001A381D33081D0300E0603551D0F0101FF0404030206C030090603551D130402300030430603551D20043C303A3038060660380A010104302E302C06082B060105050702011620687474703A2F2F7265706F7369746F72792E6569642E62656C6769756D2E6265301D0603551D0E0416041437659109E415D93B8C49EE27CE8D1E90836AC370301F0603551D230418301680145BC5455E692614597D3F8CD0602276373E71B1CE302E0603551D1F042730253023A021A01F861D687474703A2F2F6C6F63616C686F73742F63726C2F726F6F742E63726C300D06092A864886F70D01010B050003820201006A78D9F256D6646E7B108BDCE6D1D376FA982DD89584543F265526B3E725D19784722C9496CD9658C84E420BCF45CBB8756E941AEA11E860C14A1ABEFEBF2D10FB35667BBC7CC86C176E676D06C980EB6BF72EE027896BA879F85B8EBE3D384C4622F2C7932C7913947D6D9408FBD25BC7F1FEAF3775BB8FC7027F05BA8DF086D498B96CC1CA09B94B5FBF6EE36BA19571A075177B968150A8E0667E26280B32E56C7A9F6F52FC91E610CA8C4B4817F8461DDB26147C22F64BE6C87A6F47A579EBD39258FBC80175C1912E6240F3896936A554575CFF9AFBF52C95F74B3A58DA0E56EEDF2F8A9809A9B569DC4AD415D7C02BE03074D9BFD230A621AFE024652BDE5BD192A8775ED4251568AF3A3A9844E3A5903BD77AFDEF834C96B695F6FFBA12BCD93DC43E6886ECBF1F4667919B1EBC7AB5BD39BDCBCDB499BFB0C8AA292D91A326AC6EB967C0C016A66E1E14B263B3D4B0E3712347CF36049823B10908A4331C5635058E204831F1CCE04AEA103AFB18D1F5867001C699F6D8AE8EBBD785250F2EC9FC18CEE8175E975F6D47DC2433AFA8EF3131D9A034167DA08F65678448B61980754B460EF0D677A7D5C8387FE4199515242D886C40C64D3D234B5922CEF9881189762E0805EF58EE0AA6620EEA0D666F64553C60673F296493DDE245B78156EC8D5EE6162BC65DE05E5572D8FF96296A9A2F4A002857E8F37100BC48
+
+
+3F00DF014031
+010C3539323030303035363638420210534C494E336600296CFF278E5519202E030A31372E30322E32303136040A31392E30322E32303536050E4D794D756E69636970616C697479060D31393732303530313532353637070A4D794C6173746E616D65080C4D7946697273746E616D652009000A0442656C670B0B4D794269727468436974790C0B3235204D414920313936350D014D0E000F0231311114C03D39E3B4660AD8D3A9710617CBB56C7F5C2475
+
+
+3F00DF014032
+AF
+
+
+3F00DF014033
+010D4D696A6E73747261617420363302043130303003074272757373656C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+
+3F00DF014034
+AF
+
+
+3F00DF014035
+FFD8FFE000104A46494600010201012C012C0000FFDB00430007050606060507060606080807090B120C0B0A0A0B1710110D121B171C1C1A171A191D212A241D1F2820191A253225282C2D2F302F1D233438342E372A2E2F2EFFC0000B0800C8008C01011100FFC400D20000010501010101010100000000000000000102030405060708090A0B100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFDA0008010100003F00F59A28A28A28A3DA970719C71EB460FA5277C77A0F1D78A28A28A28A28A28A28AB965632DCB03B4AC79E5FFC3D6B660D36D62E76B39F5739ABA005185181E828201EA01FA8A67930E49312127D54557B8D3ED671831EC3EA9C566DCE912A9CDB9F307A1201ACC7564764604329C107A8A6D14514514514E8D1A47088A598F402B6ECB4A543BEE70CDD901E07F8D6A850A0000003B0A28A28A28ACDD62C1AE504D085F3D3D7F887A573CAC186452D145145147703D78AEA34EB74B7B68F0803B282CC47273CE2AD514514514514573FAEDAF9322DD46004908570077EC7F4ACDA28A28A2AEE956EB71743783B106E3FD2BA5A28A28A28A28A2A2BA856E2DA485B1F3A9009EC7D6B8E8D5D098A45DAC87041A928A28A2BA4D26DD61B457DB8924E5BFA7E957A8A28A28A28A28A2B9CF10C5E55DC573C00E307EA3BFE445503ED45145364384623D2BADB16DD6701FF00A66BFCAA7A28A28A28A28A28AE6FC5320F3AD62E72159BF3C7F85501D052D1452372A4574BA21CE956FF0043FCCD5EA28A28A28A28A28AE57C4BCEAB0AFF00D301FF00A11AAE38028A28A46FBA6BA7D1D1E3D3204914AB00720F51C9AB94514514514514515C9F88195F58509C848954FD724FF5A89BAD25153597946F20598128CD8C76CF6FD715D3B5BC0EC1DE18CB0E84A8C8A968A28A28A28A28A28AC3D534A964B896F2270DD0F978E7818FC6B2739EC476C1EB4544265EE3069A660278E503EE106BB953900FAD1451451451451451452D71DAD485758B945C0036F4FF007466A0132FA11F5AAD4927DC61EA2BB7D326FB4585BCBC64A0071EA383FA8AB5451451451451451452332A297760A8A32493800579DACC6E2E65B83D65667FA64D4D83553CD93FBDFA52348EC30589AECFC2F2AC9A52A0FF00964ECA78EF9CFF005AD8A28A28A28A28A28A2B1FC55702DF449FE7DAD2E22518EB93C8FF00BE41AE1EDD888D48383CD4E2690746FD2AB79C9E868F3D71C039AD4D075D4D30CA97113341236ECA75538C7427A702BB7B2BBB7BDB64B9B593CC89FA3631D3AD4F45145145145145616AFE28D334ABA6B5B8F3DA6500958E3CF519F5AE5BC43AE26B12DAADB24D1C316599640012C463A027A0FE66A8C72AAA0520E47A53BCE4F435537A7F7C7E746F4FEF0FCE918C6C305979F7AD6F086AC2C2FF00ECD71262DAE0851B8F0AFD8FE3D3F2AF48A28A28A28A28A5AF27F11C865F116A0EE08C49B3DF0063FA540BE5A7008E7BE7AD2974C13B87E746F4FEF0FCEA98E9EB477C518E7A734C9B063604E0819EB5EA3E10D446A3A15BB96CCB10F2A4CF5C81D7F1183F8D6DD14514514514633DF15E2525F9BED42E2E0E3134ACC31F5352707D28E319C0FAD2E2B30330180C40F634BBDF39DC73D339A424B72493F5A4CED04921571C93D3157BE1EF8F7C3F6BE2A3A0B6A20CD7ACB02A88DC8F346768DC063B91D7B8AF6FA4A28A28A28AE2BE2878BEC7C25A0AF9F73E4DDDF9305B000939FE26E01E808F4E48AF32B53FBBC83CE738A9B24F5A50CC060138F4CD1B8F7E7EB59D3DEADBC6649A78E3400925C81FCEB95D4FE2069166A45ABCB793E0E1114AAE7DD8FF00300D7357FF0012F589C6CB0B4B7B418FBEC3CD6CFE381FA5721A86ABAA6A008BDBFB9B90CFBB6BC84A83ECBD056BFC3D87CFF1F78663F33CB3FDA76E4363383E62E3F5C57DE9494514514515F3DFED5F8FB1F8638C9F32E47E91D79A7803C58E5A3D235299CB924433C8F9DDFEC1CFE383F857A389A418F9A813483BD1E73FAD7CE0C0BB1777666272493CD281818CD2D15E8FF00ECBEDBF13F49046560124CDC74DA848FD715F67514514514515F3C7ED5CEA20F0B21CEE67BA23E80459FE62BE7039C82A4820F04576FE1FF1DDCDA7976BAA279F1018F3C125C0F523BF6F4FC6BBEB0D6ECB50844B672C72AF7DAFCAFD4751F8D5AFB5FF00D33FFC7ABC068A28AF6CFD972CD66F1B6A578CDCDBE9EC1467BB3A73F903F9D7D53451451451457CD9FB59DCC4D75E14B40DFBE8A3B99187A2B18C0FFD01BF2AF9F690807AD58B2BDBBD3E71716333452E3048EE3D083D6BAAB4F1DCF1DBA25E5AACB30EAEA76EEFC2B8EA28A2B63C2DE24D5BC2BACDBEADA3CC63B88C8DCA49DB22E4128D8232A71C8AFBB3C3DACE9FE21D16CF5AD2E6F36CEEE31221C8CAFAAB609C3039047620D68D145145151DC4D15B5BCB713CA914312179249182AA28192493C0007735F0FF00C56F193F8D7C6575A92106C211F66B218DBFB956243107072C496E79E40ED5C751452601EA052D1451457B2FECFBF10B4FF0ADE5DE83ADDCBC361A84A8F0CCC7F7704B820EEF40C360CF6DA33C723EAE8DD258D2489D5E3750CAC872181E841EE29D4514528E7A5784FED1FE37B3B6F0F8F09E977F1C97F792E2F44122B18624E4A3E0E5
+
+
+3F00DF014038
+E0EAAC4F2D3B0FD8CD78AE57AED01BA915543E57
+
+
+3F00DF01404A
+02080000000000010001038180842A3A869015FB42F727FE5143DC22FAB85C56D2F969DCBD384C6DA1BEC39F8D0D22ED4814C2E69BBF06A3DE4CD53DDFB9F66B09EE29843AD798DD5413B55D560271FAE2A2A28997DF12AC2A7503540085E373CFE099473B42B05B66C266E29802865B3B3FB79F11AADB8084EE86BA317F9BCC49A96EA9AB89E73F673D490997
+
+
diff --git a/virtualsmartcard/src/vpicc/Makefile.am b/virtualsmartcard/src/vpicc/Makefile.am
index add04c16..c9f75d73 100644
--- a/virtualsmartcard/src/vpicc/Makefile.am
+++ b/virtualsmartcard/src/vpicc/Makefile.am
@@ -24,7 +24,8 @@ vpicccards_PYTHON = virtualsmartcard/cards/__init__.py \
virtualsmartcard/cards/ePass.py \
virtualsmartcard/cards/nPA.py \
virtualsmartcard/cards/Relay.py \
- virtualsmartcard/cards/cryptoflex.py
+ virtualsmartcard/cards/cryptoflex.py \
+ virtualsmartcard/cards/belpic.py
do_subst = $(SED) \
-e 's,[@]PYTHON[@],$(PYTHON),g' \
diff --git a/virtualsmartcard/src/vpicc/vicc.in b/virtualsmartcard/src/vpicc/vicc.in
index b016998a..6acf3210 100644
--- a/virtualsmartcard/src/vpicc/vicc.in
+++ b/virtualsmartcard/src/vpicc/vicc.in
@@ -35,7 +35,7 @@ Report bugs to @PACKAGE_BUGREPORT@
parser.add_argument("-t", "--type",
action="store",
- choices=['iso7816', 'cryptoflex', 'ePass', 'nPA', 'relay', 'handler_test'],
+ choices=['iso7816', 'cryptoflex', 'ePass', 'nPA', 'relay', 'handler_test', 'belpic'],
default='iso7816',
help="type of smart card to emulate (default: %(default)s)")
parser.add_argument("-v", "--verbose",
@@ -58,6 +58,7 @@ parser.add_argument("-P", "--port",
parser.add_argument("-R", "--reversed",
action="store_true",
help="use reversed connection mode. vicc will wait for an incoming connection from vpcd. (default: %(default)s)")
+parser.add_argument('--log-unparsed', action="store_true", help="Log unparsed command APDUs, rather than trying to parse them")
parser.add_argument('--version', action='version', version='%(prog)s @PACKAGE_VERSION@')
relay = parser.add_argument_group('Relaying a local smart card (`--type=relay`)')
@@ -156,7 +157,7 @@ vicc = VirtualICC(args.datasetfile, args.type, hostname, args.port,
readernum=args.reader, ef_cardaccess=ef_cardaccess_data,
ef_cardsecurity=ef_cardsecurity_data, ca_key=ca_key_data, cvca=cvca,
disable_checks=args.disable_ta_checks, esign_ca_cert=esign_ca_cert,
- esign_cert=esign_cert, logginglevel=logginglevel)
+ esign_cert=esign_cert, logginglevel=logginglevel, logunparsed=args.log_unparsed)
try:
vicc.run()
except KeyboardInterrupt:
diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py b/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py
index 93c5ef39..037b8d61 100644
--- a/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py
+++ b/virtualsmartcard/src/vpicc/virtualsmartcard/CardGenerator.py
@@ -665,6 +665,12 @@ def __generate_cryptoflex(self):
data="\x00\x00\x00\x01\x00\x01\x00\x00")) # EF.ICCSN
self.sam = CryptoflexSAM(self.mf)
+ def __generate_belpic(self):
+ from virtualsmartcard.cards.belpic import BelpicMF
+ self.__generate_iso_card()
+ self.mf = BelpicMF('belpic.xml')
+ self.sam.set_MF(self.mf)
+
def generateCard(self):
"""Generate a new card"""
if self.type == 'iso7816':
@@ -675,6 +681,8 @@ def generateCard(self):
self.__generate_cryptoflex()
elif self.type == 'nPA':
self.__generate_nPA()
+ elif self.type == 'belpic':
+ self.__generate_belpic()
else:
return (None, None)
diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py
index a8c6377f..26fe26f6 100644
--- a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py
+++ b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py
@@ -56,6 +56,11 @@ def execute(self, msg):
"""
return ""
+ def logAPDU(self, parsed, unparsed):
+ if(self.logunparsed):
+ logging.info("Unparsed APDU:\n%s", hexdump(unparsed));
+ else:
+ logging.info("Parsed APDU:\n%s", str(parsed))
class Iso7816OS(SmartcardOS):
@@ -286,7 +291,7 @@ def notImplemented(*argz, **args):
return self.formatResult(False, 0, "",
SW["ERR_INCORRECTPARAMETERS"], False)
- logging.info("Parsed APDU:\n%s", str(c))
+ self.logAPDU(parsed=c, unparsed=msg)
# Handle Class Byte
# {{{
@@ -391,7 +396,7 @@ def __init__(self, datasetfile, card_type, host, port,
readernum=None, ef_cardsecurity=None, ef_cardaccess=None,
ca_key=None, cvca=None, disable_checks=False, esign_key=None,
esign_ca_cert=None, esign_cert=None,
- logginglevel=logging.INFO):
+ logginglevel=logging.INFO, logunparsed=False):
from os.path import exists
logging.basicConfig(level=logginglevel,
@@ -428,12 +433,16 @@ def __init__(self, datasetfile, card_type, host, port,
elif card_type == "handler_test":
from virtualsmartcard.cards.HandlerTest import HandlerTestOS
self.os = HandlerTestOS()
+ elif card_type == "belpic":
+ from virtualsmartcard.cards.belpic import BelpicOS
+ self.os = BelpicOS(MF, SAM)
else:
logging.warning("Unknown cardtype %s. Will use standard card_type \
(ISO 7816)", card_type)
card_type = "iso7816"
self.os = Iso7816OS(MF, SAM)
self.type = card_type
+ self.os.logunparsed = logunparsed
# Connect to the VPCD
self.host = host
diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/cards/Relay.py b/virtualsmartcard/src/vpicc/virtualsmartcard/cards/Relay.py
index 69c27b3e..4ef33d0d 100644
--- a/virtualsmartcard/src/vpicc/virtualsmartcard/cards/Relay.py
+++ b/virtualsmartcard/src/vpicc/virtualsmartcard/cards/Relay.py
@@ -22,7 +22,7 @@
import smartcard
import sys
from virtualsmartcard.VirtualSmartcard import SmartcardOS
-
+from virtualsmartcard.utils import C_APDU
class RelayOS(SmartcardOS):
"""
@@ -113,6 +113,13 @@ def reset(self):
self.powerUp()
def execute(self, msg):
+ try:
+ c = C_APDU(msg)
+ self.logAPDU(parsed=c, unparsed=msg)
+ except ValueError as e:
+ # ignore the parse failure, just don't log the parsed APDU
+ logging.warning("Could not parse APDU:%s", str(e))
+
# sendCommandAPDU() expects a list of APDU bytes
apdu = map(ord, msg)
diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/cards/belpic.py b/virtualsmartcard/src/vpicc/virtualsmartcard/cards/belpic.py
new file mode 100644
index 00000000..3d2fa59c
--- /dev/null
+++ b/virtualsmartcard/src/vpicc/virtualsmartcard/cards/belpic.py
@@ -0,0 +1,116 @@
+#
+# Copyright (C) 2017 Wouter Verhelst, Federal Public Service BOSA, DG DT
+#
+# This file is part of virtualsmartcard.
+#
+# virtualsmartcard is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# virtualsmartcard is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# virtualsmartcard. If not, see .
+
+from virtualsmartcard.VirtualSmartcard import Iso7816OS
+from virtualsmartcard.ConstantDefinitions import MAX_SHORT_LE, FDB, LCB, REF
+from virtualsmartcard.SmartcardFilesystem import MF, DF, TransparentStructureEF
+from virtualsmartcard.SWutils import SW, SwError
+from virtualsmartcard.utils import C_APDU, R_APDU
+
+import logging
+
+import xml.etree.ElementTree as ET
+
+class BelpicOS(Iso7816OS):
+ def __init__(self, mf, sam, ins2handler=None, maxle=MAX_SHORT_LE):
+ Iso7816OS.__init__(self, mf, sam, ins2handler, maxle)
+ self.ins2handler = {
+ 0xc0: self.getResponse,
+ 0xa4: self.mf.selectFile,
+ 0xb0: self.mf.readBinaryPlain,
+ 0x20: self.SAM.verify,
+ 0x24: self.SAM.change_reference_data,
+ 0x22: self.SAM.manage_security_environment,
+ 0x2a: self.SAM.perform_security_operation,
+ 0xe4: self.getCardData,
+ 0xe6: self.logOff
+ }
+ self.atr = '\x3B\x98\x13\x40\x0A\xA5\x03\x01\x01\x01\xAD\x13\x11'
+
+ # TODO: don't hardcode the value below, so that we can also emulate the v1.1 applet
+ def getCardData(self, p1, p2, data):
+ return SW["NORMAL"], "534C494E0123456789ABCDEF01234567F3360125011700030021010f".decode("hex")
+
+ # TODO: actually log off
+ def logOff(self, p1, p2, data):
+ return SW["NORMAL"]
+
+ def execute(self, msg):
+ c = C_APDU(msg)
+ if (c.ins == 0xa4 and c.p1 == 0x02):
+ # The belpic applet is a bit loose with interpretation of
+ # the ISO 7816 standard on the A4 command:
+ # - The MF can be selected by name from anywhere with P1 ==
+ # 0x02, rather than 0x00 as ISO 7816 requires
+ if (c.data == '3F00'.decode('hex')):
+ logging.info("Original APDU:\n%s\nRewritten to:\n", str(c))
+ c.p1 = 0
+ msg = c.render()
+ # - Child DFs can be selected with P1 == 0x02, rather than
+ # 0x01 as ISO 7816 requires
+ if (c.data == 'DF00'.decode('hex') or c.data == 'DF01'.decode('hex')):
+ logging.info("Original APDU:\n%s\nRewritten to:\n", str(c))
+ c.p1 = 1
+ msg = c.render()
+ return Iso7816OS.execute(self, msg)
+
+ def formatResult(self, seekable, le, data, sw, sm):
+ r = R_APDU(Iso7816OS.formatResult(self, seekable, le, data, sw, sm))
+ # The Belpic applet provides a bogus file length of 65536 for
+ # every file, and does not return an error or warning when the
+ # actual file length is shorter that the file as found; so
+ # filter out the EOFBEFORENEREAD warning
+ if (r.sw1 == 0x62 and r.sw2 == 0x82):
+ logging.info("Filtering out warning")
+ r.sw = "9000".decode("hex")
+ return r.render()
+
+class BelpicMF(MF):
+ def __init__(self, datafile, filedescriptor=FDB["NOTSHAREABLEFILE" ] | FDB["DF"],
+ lifecycle=LCB["ACTIVATED"],simpletlv_data = None, bertlv_data = None):
+ MF.__init__(self, filedescriptor, lifecycle, simpletlv_data, bertlv_data, dfname = "A00000003029057000AD13100101FF".decode('hex'))
+ tree = ET.parse(datafile)
+ root = tree.getroot()
+ ns = {'f': 'urn:be:fedict:eid:dev:virtualcard:1.0'}
+ DF00 = DF(self, 0xDF00, dfname="A000000177504B43532D3135".decode('hex'))
+ self.append(DF00)
+ DF01 = DF(self, 0xDF01)
+ self.append(DF01)
+ parent = self
+ fid = 0
+ for f in root.findall('f:file', ns):
+ id = f.find('f:id', ns).text
+ content = f.find('f:content', ns).text
+ if content is not None:
+ if(len(id) == 12):
+ fid = int(id[8:], 16)
+ if (id[4:8] == 'DF00'):
+ parent = DF00
+ if (id[4:8] == 'DF01'):
+ parent = DF01
+ else:
+ fid = int(id[4:], 16)
+ parent.append(TransparentStructureEF(parent, fid, data = content.decode('hex')))
+
+ def select(self, attribute, value, reference=REF["IDENTIFIER_FIRST"], index_current=0):
+ if (hasattr(self, attribute) and
+ ((getattr(self, attribute) == value) or
+ (attribute == 'dfname' and
+ getattr(self, attribute).startswith(value)))):
+ return self
+ return DF.select(self, attribute, value, reference, index_current)