jCardsim and Raspberry Pi Hackathon

Tags: jcardsim, Java Card, raspberry pi, linux, hackathon

Привет всем!

В ноябре произошло несколько интересных событий в жизни нашего проекта, о которых мы хотели бы рассказать.

Статуэтка Java Duke Choice Awards, которую получил jCardSim, приехала в Москву! Ура! Еще раз спасибо Oracle и судьям конкурса!

Licel's jCardSim Project is a winner of Oracle Duke's Choive Award 2013

На прошлой неделе наша команда провела Raspberry Pi Hackathon. Его целью было придумать и реализовать идею, как можно подружить jCardSim и Raspberry Pi.

jCardSim and Raspberry Pi

Raspberry Pi – очень интересная, популярная и, главное, доступная для разработчика платформа. Архитектурно в ней используются многие компоненты из мира современных карточных чипов, например, ARM-процессор. К тому же для Linux на Raspberry Pi есть Java 7 Embedded. Отлично, подумали мы, и решили попробовать, и устроили Raspberry Pi Hackathon. Архитектуру решения мы придумали сразу: на Raspberry Pi плате запускается jCardSim и эмулирует Java Card, а дальше к нему подключается клиентское приложение и работает с ним.

jCardSim and Raspberry Pi

Вначале надо было определиться с протоколом взаимодействия, у нас была в распоряжении модель Raspberry Pi B, которая, к сожалению, поддерживает USB только в режиме USB-host, поэтому остался только один путь: использовать сетевое подключение к устройству. Как позже оказалось, это позволило добавить еще одну крутую фичу в jCardSim.

Далее Иван Кинаш (наш CEO) занялся установкой Linux и Java 7 Embedded на Raspberry Pi. А я начал распиливать jCardSim на клиент и сервер. Вначале надо было выделить общий интерфейс, который бы предоставляла обычная in-memory и удаленная реализация Simulator.

В результате получилась следующая картина (полный класс c javadoc):
https://github.com/licel/jcardsim/blob/Raspberry_Pi_Hackathon/src/main/java/com/licel/jcardsim/io/CardInterface.java:

public interface CardInterface {
   public void reset();
   public byte[] getATR();
   public byte[] transmitCommand(byte[] data);
}

и https://github.com/licel/jcardsim/blob/Raspberry_Pi_Hackathon/src/main/java/com/licel/jcardsim/io/JavaCardInterface.java:

public interface JavaCardInterface extends CardInterface {
   public AID loadApplet(AID aid, String appletClassName, byte[] appletJarContents) throws SystemException;
   public AID loadApplet(AID aid, String appletClass);
   public AID createApplet(AID aid, byte bArray[], short bOffset, byte bLength) throws SystemException;
   public AID installApplet(AID aid, String appletClassName, byte bArray[], short bOffset, byte bLength) throws SystemException;
   public AID installApplet(AID aid, String appletClassName, byte[] appletJarContents, byte bArray[], short bOffset, byte bLength) throws SystemException;
   public boolean selectApplet(AID aid);
}

Обратите внимание, мы здесь добавили 2 метода:

   public AID loadApplet(AID aid, String appletClassName, byte[] appletJarContents) throws SystemException;
   public AID installApplet(AID aid, String appletClassName, byte[] appletJarContents, byte bArray[], short bOffset, byte bLength) throws SystemException;

Реализация этих методов позволит загружать на Raspberry Pi jar-файл с апплетом и классами, необходимыми для его работы.

Немного рефакторинга, прогоняем unit-тесты, и in-memory реализация работает. К тому времени на Raspberry Pi был уже установлен Raspbian и Java 7 Embedded.

Скопировали in-memory реализацию на малинку, запустили - работает. Хотя, кто бы сомневался :-)

Теперь нужно реализовать сервер и протокол взаимодействия с ним. Я – old school java guy, поэтому для таких вещей я люблю использовать Java RMI. Минимум кода, простота работы, что еще нужно для Hackathon. Ну, разве что отличную атмосферу и суши :-)

Кодируем, запускает, не работает... Оказывается, при установке Raspbian появилась странная запись в /etc/hosts:
127.0.1.1 raspberry-pi
По каким-то причинам, она мешала RMI Registry нормально работать. После удаления этой строчки все работает. APDUScriptTool через javax.smartcardio взаимодействует с апплетами внутри jCardSim на Raspberry Pi.

Чтобы поделиться результатами со всеми jCardSim пользователями и не повлиять на стабильность master, выполняем на локальном git:

git checkout -b Raspberry_Pi_Hackathon
git commit -m ""
git pull

Готово: https://github.com/licel/jcardsim/tree/Raspberry_Pi_Hackathon

Чтобы проверить результаты, совсем необязательно иметь Raspberry Pi в наличии, хотя, поверьте, с ней все гораздо интереснее.

Качаем jcardsim-2.2.1-all.jar, apdu.script, jcardsim.cfg из ветки Raspberry_Pi_Hackathon.

Для запуска сервера:
java -jar jcardsim-2.2.1-all.jar com.licel.jcarsim.remote.JavaCardRemoteServer jcardsim.cfg

Для клиента, как и обычно:
java -jar jcardsim-2.2.1-all.jar com.licel.jcarsim.utils.APDUScriptTool jcardsim.cfg apdu.script

Сервер и порт, на котором работает jCardSim Server, задается следующими настройками в jcardsim.cfg:

com.licel.jcardsim.terminal.host=localhost
com.licel.jcardsim.terminal.port=1234

Урра! Цель достигнута, jCardSim получил новый интересный функционал, который скоро будет перенесен в master, ведь еще нужно написать кучу документации и добавить unit-тестов. А Raspberry Pi подтвердил звание одной из лучших developer embedded платформ.

P.S.
Кстати, в ходе нашего хакатона, мы обнаружили очень крутой дистрибутив для Raspberry Pi - Raspnmc (http://www.raspbmc.com). Если вам нужно решение для медиа-центра или просто сетевой медиа-плеер, то Raspberry Pi с Raspnmc - это отличный выбор!

Всем спасибо! Успехов!