{"id":17278134,"url":"https://github.com/mingun/pcsc-cenxfs-bridge","last_synced_at":"2025-03-26T14:22:16.794Z","repository":{"id":141717680,"uuid":"207104545","full_name":"Mingun/pcsc-cenxfs-bridge","owner":"Mingun","description":"Мост между стандартом для взаимодействия карт PC/SC и CEN/XFS. Предоставляет XFS-провайдер для любого PC/SC-совместимого карточного считывателя","archived":false,"fork":false,"pushed_at":"2019-09-08T11:50:40.000Z","size":1439,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-31T15:40:07.341Z","etag":null,"topics":["bridge","chip","emv","pcsc","xfs"],"latest_commit_sha":null,"homepage":"https://bitbucket.org/Mingun/pcsc-cenxfs-bridge","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mingun.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-08T11:47:18.000Z","updated_at":"2024-03-03T21:15:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"52309c3e-b6d7-4aa1-8ee4-15ff8e298a58","html_url":"https://github.com/Mingun/pcsc-cenxfs-bridge","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mingun%2Fpcsc-cenxfs-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mingun%2Fpcsc-cenxfs-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mingun%2Fpcsc-cenxfs-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mingun%2Fpcsc-cenxfs-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mingun","download_url":"https://codeload.github.com/Mingun/pcsc-cenxfs-bridge/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245668650,"owners_count":20653011,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bridge","chip","emv","pcsc","xfs"],"created_at":"2024-10-15T09:10:53.426Z","updated_at":"2025-03-26T14:22:16.761Z","avatar_url":"https://github.com/Mingun.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"PC/SC-CEN/XFS-bridge\r\n====================\r\nДанный проект реализует мост между протоколами [PC/SC][1] (протокол для общения c smart-картами)\r\nи протоколом [CEN/XFS][2], используемом банкоматным ПО для доступа к устройствам, в том числе\r\nчиповым считывателям карт.\r\n\r\nЛицензия\r\n--------\r\nЛицензия MIT. Вкратце, возможно бесплатное использование в коммерческих и открытых проектах. Текст\r\nлицензии на русском и английском языках в файле LICENSE.md. Юридическую силу имеет только английский\r\nвариант.\r\n\r\nЗависимости\r\n-----------\r\n1. Boost (должна быть прописана переменная окружения `%BOOST_ROOT%`, указывающая на корневой каталог\r\nboost-а, т.е. каталог, содержащий папки libs, doc, stage и т.п. предполагается, что boost собран в\r\nкаталог по умолчанию, коим является stage)\r\n    1. `boost.chrono`\r\n    2. `boost.thread`\r\n    3. `boost.date_time` (зависимость от `boost.thread`)\r\n2. [XFS SDK][1]\r\n    1. взять можно у проекта [freexfs][4]. Там же содержится и документация.\r\n    2. Также можно взять на официальном FTP-сайте, но его достаточно трудно отыскать. На официальном\r\n       сайте группы CEN/XFS найти ссылки на документацию не удалось, к счастью, пользователь **winner13**\r\n       в форума [bankomatchik.ru][6] каким-то чудом отыскал [FTP-ссылку][7].\r\n3. Подсистема PC/SC являтется частью SDK Windows.\r\n\r\nСборка\r\n------\r\nПодготовить зависимости: скачать буст и собрать необходимые библиотеки. Сборку можно выполнить следующим образом:\r\n1. Запустить командную строку Visual Studio\r\n2. Перейти в `%BOOST_ROOT%`\r\n3. Выполнить команду `bootstrap.bat msvc` для сборки инструмента сборки буста\r\n4. Выполнить команду `build-boost.bat` из корня проекта для сбора необходимых библиотек в нужном варианте\r\n\r\nЗапустить командную строку Visual Studio и выполнить в ней команду\r\n```\r\nmake\r\n```\r\nЛибо открыть обычную командную строку в выполнить команды, предварительно заменив `%VC_INSTALL_DIR%`\r\nна путь к установленной MSVC. Так как Kalignite собран под x86, то и библиотеку будем собирать под\r\nэту архитектуру. Естественно, когда появится 64-битная версия, необходимо будет использовать `x86_amd64`:\r\n```\r\n\"%VC_INSTALL_DIR%\\VC\\vcvarsall.bat\" x86\r\nmake\r\n```\r\n\r\nИспользуется C++03. Проверена сборка следующими компиляторами:\r\n\r\n1. MSVC 2005\r\n2. MSVC 2008\r\n3. MSVC 2013\r\n\r\nАрхитектура\r\n-----------\r\nПри загрузке динамической библиотеки создается глобальный объект `Manager`, в конструкторе которого\r\nинициализируется подсистема PC/SC и запускается поток опроса изменений в устройствах и подключения\r\nновых устройств. В деструкторе глобального объекта соединение с подсистемой PC/SC закрывается, это\r\nпроисходит автоматически, когда менеджер XFS выгружает библиотеку.\r\n\r\nХотя может показаться, что можно было напрямую мапить хендл сервис-провайдера (`HSERVICE`), на хендл\r\nконтекста PC/SC (`SCARDCONTEXT`), этого не делается потому, что функция `SCardListReaders` блокирующая,\r\nа она требует хендл контекста. Таким образом, если бы на каждый сервис-провайдер был заведен свой PC/SC\r\nконтекст, потребовалось бы на каждый создавать по своему потоку для опроса изменений в устройствах.\r\n\r\nКласс `Manager` содержит список задач на чтение карты, которые создаются при вызове метода `WFPExecute`,\r\nи список сервисов, представляющих открытые XFS-менеджером сервисы (через `WFPOpen`).\r\n\r\nКогда происходит событие PC/SC, отдельный поток сначала уведомляет все подписавшиеся окна (через\r\n`WFPRegister`) на изменения (естественно, выполняется трансляция события из PC/SC в XFS форму), а\r\nзатем уведомляет все задачи обо всех произошедших изменениях. Таким образом реализуется требование\r\nXFS, что все события должны быть испущены до того, как произойдет `WFS_xxx_COMPLETE`-событие.\r\n\r\nЕсли задача считает, что изменение ей интересно, она генерирует событие `WFS_xxx_COMPLETE` и ее метод\r\n`match` возвращает `true`, в результате чего она удаляется из списка задач.\r\n\r\nСобытия о завершении отправляются Windows функцией PostMessage, которая укладывает ее в очередь сообщений\r\nпотока, который обрабатывает события завершения. На совести конечного приложения, что оно предоставляет\r\nхендлы окон, которые существуют в одном потоке, иначе `WFS_xxx_COMPLETE`-событие может прийти раньше,\r\nчем прочие виды событий. Кроме того, если события приложения обрабатывает в другом потоке, чем асинхронные\r\nвызовы сервис-провайдера, то события могут прийти раньше, чем завершится асинхронный вызов, их инициирующий.\r\nНа совести приложения работать правильно в таком случае и не терять уведомления. Это особенность XFS API,\r\nоно предъявляет очень жесткие требования к приложению.\r\n\r\nНастройки\r\n---------\r\nБольшинство настроек предназначены для обхода проблем, обнаруженных в процессе тестирования, но некоторые\r\nуправляют штатным функционалом сервис-провайдера. Все настройки выполняются в ветке реестра, под веткой\r\nс провайдером логического сервиса (`HKEY_LOCAL_MACHINE\\SOFTWARE\\XFS\\SERVICE_PROVIDERS\\\u003cпровайдер\u003e`).\r\nВсе `DWORD` значения в таблице являются логическими флагами, со значением `0` -- сброшены, любое другое --\r\nвыставлен:\r\n\r\nНазвание        |Тип     |Назначение\r\n----------------|--------|----------\r\nReaderName      |`REG_SZ`|PC/SC название считывателя, с которым должен работать данный провайдер. Если параметр пустой или отсутствует, то слушаются все подключенные считыватели и используется первый, в который будет вставлена карточка (это делается каждый раз, т.е. если карточку вытащили из первого считывателя и вставили во второй, то работа будет происходить со вторым считывателем). Если не пустой, то событие вставки карты будет обрабатываться только от указанного считывателя\r\nExclusive       |`DWORD` |Если флаг установлен, то считыватель будет использовать карту в монопольном режиме (`SCARD_SHARE_EXCLUSIVE`), т.е. никто, кроме сервис-провайдера, не сможет общаться с картой одновременно. Если сброшен или отсутсвует, то карта открывается в совместном режиме (`SCARD_SHARE_SHARED`)\r\n**Workarounds** |        |Подраздел -- обходы багов\r\nCorrectChipIO   |`DWORD` |Анализировать длину передаваемых чипу команд и корректировать ее в соответствии с тем, что передается в заголовке команды. Kalignite может передавать лишние байты в команде чтения, а это вызывает ошибку у функции `SCardTransmit`. Если сброшен или отсутствует, то анализ не производится\r\nCanEject        |`DWORD` |Сообщать, что устройство умеет извлекать карты в возможностях устройства и принимать команду извлечения карты (`WFS_CMD_IDC_EJECT_CARD`). При этом ничего не делается. Если сброшен или отсутствует, то в возможностях сообщать, что команда не поддерживается, а при получении этой команды возвращать ошибку **неподдерживаемая команда** (`WFS_ERR_UNSUPP_COMMAND`). Kalignite пытается выдавать карту, даже если эта возможность не поддерживается, и не ожидает, что команда не будет выполнена, падая с Fatal Error в случае кода ответа, отличного от успеха\r\n**Track2**      |        |Подраздел **Workarounds** -- настройки второй дорожки\r\n_(по умолчанию)_|`REG_SZ`|Значение второй дорожки, сообщаемое провайдером, без начального и конечного разделителей, как будет отдано приложению. Значение сообщается, только если флаг `Report` взведен\r\nReport          |`DWORD` |Сообщать о возможности чтения второй магнитной дорожки. Если флаг взведен, а значение трека пустое, то при чтении возвращается код ошибки **данные отсутствуют** (`WFS_IDC_DATAMISSING`). Если флаг сброшен, то в возможностях устройства сообщается, что чтение второй дорожки не поддерживается. Kalignite требует, чтобы вторая дорожка была прочитана, даже если в условиях чтения указать не читать вторую дорожку (на момент чтения все в порядке, но потом при работе сценария он падает с Fatal Error из-за отсутствия второй дорожки)\r\n\r\nПротестированные считыватели\r\n----------------------------\r\nДля работы с Kaliginte-ом были активированы все обходы багов.\r\n\r\n1. [OMNIKEY 3121][5] (pcsc_scan знает его, как OMNIKEY AG Smart Card Reader USB 0) -- успешно работает\r\n2. [ACR38u][8] -- успешно работает\r\n\r\n[1]: http://www.pcscworkgroup.com/\r\n[2]: http://www.cen.eu/work/areas/ict/ebusiness/pages/ws-xfs.aspx\r\n[3]: https://code.google.com/p/freexfs/downloads/detail?name=XFS%20SDK3.0.rar\u0026can=2\u0026q=\r\n[4]: https://code.google.com/p/freexfs/\r\n[5]: http://www.hidglobal.com/products/readers/omnikey/3121\r\n[6]: http://bankomatchik.ru/forums/topic/4654#p65827\r\n[7]: ftp://ftp.cenorm.be/PUBLIC/CWAs/other/WS-XFS/SDK%20XFS3/sdk303.zip\r\n[8]: http://www.acr38u.com/","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmingun%2Fpcsc-cenxfs-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmingun%2Fpcsc-cenxfs-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmingun%2Fpcsc-cenxfs-bridge/lists"}