bcrypto / btok

Cryptographic tokens
4 stars 4 forks source link

Запись/чтение файла с одновременным выбором #54

Closed olegotory closed 5 years ago

olegotory commented 5 years ago

В стандарте для записи/чтения двоичного файла (команды update/read binary) используется один из стандартных подходов ISO 7816: перед записью/чтением файла требуется его предварительно выбрать (командой select file). При выборе файла указывается его FID, состоящий из 2-x октетов. В стандарте ISO 7816 для команд записи/чтения двоичного файла дополнительно предусмотрен режим, который не требует предварительного выбора файла, при этом в команде записи/чтения указывается SFID (значение от 1 до 29, которое назначается файлу) и смещение (до 255 байтов). Такой режим использования команды позволяет более быстро записать/прочитать данные, так как не требуется предварительно выполнять команду выбора файла. Однако размер файла при этом ограничен (максимум = 255 (макс. смещение) + 243 (макс. размер, который может быть возвращен в защищенном ответе) = 498 октетов). В стандарте нет прямого запрета на использование команд с SFID, поэтому считаю, что при необходимости, для некоторых файлов можно будет ввести SFID и разрешить писать/читать данные по SFID. Отмечу, что в eIDAS при описании eSign вводятся SFID только для двух файлов: EF.CIAInfo -- файл, который определяет основную информацию о токене и приложении, EF.OD -- файл, в котором приводится список объектов с указанием файлов, в которых хранятся объекты.

andrewkostevich commented 5 years ago

В ISO7816 команда READ BINARY поддерживает режим одновременного выбора и чтения данных:

В ISO7816 введена команда GET DATA, которая поддерживает режим одновременного выбора и чтения данных:

Синтаксис команды GET DATA более естественный:

предлагаю использовать именно его

agievich commented 5 years ago

Система команд BTOK -- это базовая система. Конечно, она может расширяться. Дополнительные команды могут вводиться сначала в реализациях, а затем переноситься (по согласованию с заинтересованными сторонами) в новые редакции BTOK. Это нормальный процесс стандартизации. Мы все к нему стремимся. Поэтому вопросу назначается метка "future plans". Это специальная метка для потенциальных будущих расширений.

И еще один аспект. Базовые команды -- это команды "без которых нельзя". Предложенные команды -- это команды "без которых можно". По-видимому, подобные команды следует определять не в основной части стандарта, а в необязательных приложениях.

Отмечу, что поддержка предложенных команд увеличивает stateful-нагрузку КТ: требуется хранить список открытых файлов и файловые указатели для каждого из них. Вполне жизнеспособны случаи, когда нагрузка велика и разработчики откажутся от использования расширения.

andrewkostevich commented 5 years ago

Отмечу, что поддержка предложенных команд увеличивает stateful-нагрузку КТ: требуется хранить список открытых файлов и файловые указатели для каждого из них.

stateful-нагрузка на КТ одинакова: в текущей системе команд нужно хранить идентификатор открытого файла (2 байта), в предлагаемой команде (INS=CB) нужно хранить идентификатор открытого файла (2 байта) и смещение в открытом файле (2 байта). Прирост нагрузки на RAM в 2 байта не кажется проблемой.

Базовые команды -- это команды "без которых нельзя". Предложенные команды -- это команды "без которых можно".

Предложение состоит в замене базовых команд на эквивалентные по функционалу но с более высоким быстродействием и более информативными:

  1. Быстродействие предлагаемых команд выше по сравнению с текущей парой команд (SELECT/READ или WRITE): полностью отсутствуют накладные расходы на обработку SELECT: снятие защиты команды (расшифрование/проверка имитовставки), обработку SELECT, установку защиты на ответ (зашифрование/выработка имитовставки). Всего обращение к eID сокращается на 13 команд.
  2. Предлагаемые команды более информативны:
    • в случае GET DATA c INS=CB КП и терминалу известно сколько байт осталось прочитать из файла: READ BINARY не позволяет это сделать, требуется или выполнять дополнительные операции чтения до получения ошибки от КТ или знать структуру файла и выпаршивать из него длину
    • в случае PUT DATA c INS=DB КТ знает, требуется ли закрыть файл после завершения записи или нет: синтаксис UPDATE BINARY не позволяет передать признак необходимости закрытия файла, в связи с чем возможна утеря целостности файла при обрыве связи с терминалом/КП
agievich commented 5 years ago

Команда SELECT нужна для навигации в файловой системе КТ. Да, сейчас эта система не очень развита -- все нужные файлы находятся на одном уровне. Но файловая система может расширяться, мы не можем заблокировать возможность навигации. Поэтому SELECT -- это то, "без чего нельзя".

Stateful-нагрузка возрастает, потому что в предлагаемой модели может быть одновременно открыто несколько файлов. И для каждого нужно поддерживать состояние.

Про PUT DATA речь вообще не шла. Еще раз предлагаю оформлять предложения в виде законченного PR.

andrewkostevich commented 5 years ago

Команда SELECT нужна для навигации в файловой системе КТ. Да, сейчас эта система не очень развита -- все нужные файлы находятся на одном уровне. Но файловая система может расширяться.

Но это только планы на будущее. Это все можно будет сделать в будущих версиях стандарта и новых версиях КТ

Stateful-нагрузка возрастает, потому что в предлагаемой модели может быть одновременно открыто несколько файлов. И для каждого нужно поддерживать состояние.

Stateful-нагрузка аналогичная: модель с GET DATA в режиме INS=CB в этой части идентична паре SELECT/READ: может быть открыт только один файл. Но GET DATA более эффективна при использовании защищенного соединения.

Про PUT DATA я поясню на примере: рассмотрим перевыпуск сертификата на КТ

IMHO, это серьезные проблемы использованной системы команд.

Предлагаемая система GET DATA/PUT DATA избавлена этих недостатков, имеет более естественный синтаксис:

olegotory commented 5 years ago

Команда SELECT нужна для навигации в файловой системе КТ. Да, сейчас эта система не очень развита -- все нужные файлы находятся на одном уровне. Но файловая система может расширяться.

Но это только планы на будущее. Это все можно будет сделать в будущих версиях стандарта и новых версиях КТ

Команда SELECT кроме выбора элементарных файлов нужна также и для выбора файлов-директория (мастер-файла, приложения). Например, при выработке подписи после успешной аутентификации требуется предварительно выбрать с помощью SELECT приложение eSign.

IMHO, это серьезные проблемы использованной системы команд.

В ЕС не видят проблем в использовании системы команд, которую мы заимствовали у них для нашего стандарта. Например:

  1. В "Signature creation and administration for eIDAS token. Part 1: Functional Specification" (см. https://www.ssi.gouv.fr/uploads/2015/09/eidas_tr_signature_part1_v1_rc9-4.pdf) для чтения/записи сертификатов используется команда READ BINARY/UPDATE BINARY, при этом GET DATA/PUT DATA не поддерживаются.

  2. В общеевропейском стандарте EN 419212-1:2014 "Application Interface for smart cards used as Secure Signature Creation Devices. Basic services" для чтения сертификатов используется READ BINARY, при этом для чтения определенных данных (например, параметров dh-ключа) в дополнение к команде READ BINARY можно использовать как альтернативный вариант команду GET DATA. Есть более новая версия данного стандарта (EN 419212-1:2017), стандарт платный.

Считаю, что от READ BINARY/UPDATE BINARY отказываться нельзя. Команды GET DATA/PUT DATA можно использовать как дополнительные (в новых версиях стандарта).

andrewkostevich commented 5 years ago

Команда SELECT кроме выбора элементарных файлов нужна также и для выбора файлов-директория (мастер-файла, приложения). Например, при выработке подписи после успешной аутентификации требуется предварительно выбрать с помощью SELECT приложение eSign.

Никто не против команды SELECT для других задач, но пара SELECT/READ для чтения данных менее эффективна чем GET DATA

В "Signature creation and administration for eIDAS token. Part 1: Functional Specification" (см. https://www.ssi.gouv.fr/uploads/2015/09/eidas_tr_signature_part1_v1_rc9-4.pdf) для чтения/записи сертификатов используется команда READ BINARY/UPDATE BINARY, при этом GET DATA/PUT DATA не поддерживаются.

Это потому что европейцы не сами писали систему команд для eSign, а заимствовали из PKCS#15 для обеспечения совместимости с существующим ПО: посмотрите внимательно, они везде отсылают к ISO/IEC 7816-15 (он же PKCS#15). Если бы в нашем стандарте была объявлена задача совместимости с PKCS#15, то разумеется нужно было бы использовать их систему APDU команд. Аналогично и с ICAO: для совместимости европейцы используют READ. Там же, где им не нужно обеспечивать совместимость с другими стандартами и существующим ПО, там они используют GET DATA/PUT DATA и даже нестандартные команды (MANAGE DATA).

В ЕС не видят проблем в использовании системы команд,

У них своя специфика, у нас своя:

agievich commented 5 years ago

Предложенный интерфейс GET DATA/PUT DATA не является самодостаточным:

Поэтому текущий интерфейс SELECT/READ BINARY/UPDATE BINARY нужно сохранять, а интерфейс GET DATA/PUT DATA рассматривать как дополнительный.

При разработке дополнительного интерфейса (еще раз предлагаю оформить его как приложение к BTOK и представить в виде PR) следует учесть следующие моменты:

  1. Должно быть четко определено, сколько файлов может быть открыто одновременно.
  2. Должно быть определены правила изменения файлового указателя при вызове цепочек команд (GET DATA, PUT DATA), (GET DATA, SELECT), (PUT DATA, READ BINARY) и т.д.
andrewkostevich commented 5 years ago

Как решается проблема UPDATE BINARY с невозможностью задать размер перезаписываемого файла?

olegotory commented 5 years ago

Непонятно о какой проблеме идет речь? Зачем нужно задавать размер перезаписываемого файла? UPDATE BINARY - это стандартная команда ISO 7816.

andrewkostevich commented 5 years ago

Еще раз рассмотрим перевыпуск сертификата на КТ:

Еще хуже, если выполняется обновление сертификата без перегенерации ключа (СТБ 34.101.78 не запрещает такой сценарий):

olegotory commented 5 years ago

Я понимаю так, что размеры всех файлов фиксированные и не меняются в процессе эксплуатации (файл может быть записан частично), размеры определяются на этапе программирования карты и, возможно, объявляются в некотором документе (для разработчиков, которые будут писать ПО для работы с картой), т.е. у карты простейшая файловая система, не предполагающая изменения размеров файлов. Первоначально файлы заполняются нулями. Все данные в файлах хранятся в формате T-L-V (включая сертификаты). Считав первую (начальную) порцию можно понять какой размер остальных "полезных" данных (по L).

По поводу

запись нового сертификата может осуществляться не по последовательным смещениям, а по произвольными (стандарт это не запрещает этого): что делать если какой-то фрагмент посередине не был записан?

отвечу так. Любая команда либо выполняет нужные действия, либо возвращает ошибку. Если команда вернула ошибку, то можно попытаться повторно записать данные, если еще раз вернула ошибку, то значит, что карта вышла из строя, т.е. "нерабочая."

agievich commented 5 years ago

Вопрос достаточно обсужден. Откладывается.