Как внедрить пользовательский код ввода-вывода с помощью cryptlib?

#c #ssl #cryptlib

Вопрос:

Я использую cryptlib Питера Гутмана для реализации шифрования TLS.

Обычно функции cryptPopData cryptlib и cryptPushData будут обрабатывать определенные для протокола рукопожатия, шифровать или расшифровывать данные, а также считывать или записывать в сетевой сокет, который внутренне управляется cryptlib. Это сработало, но теперь мне нужно самому реализовать ввод-вывод (а API ввода-вывода не совместим с сокетами).

Что должно произойти, примерно так(1):

 [I prepare] unencrypted TxData -> [cryptlib] -> encrypted TxData -> [I send]
[I receive] encrypted RxData -> [cryptlib] -> decrypted RxData -> [I process]
 

Согласно главе «Управление собственными сетевыми подключениями и вводом-выводом» в руководстве cryptlib, стр. 127, этот точный сценарий должен быть возможен, но я его не понимаю.

Вы также можете использовать это средство, если хотите использовать любые высокопроизводительные возможности ввода-вывода, предоставляемые вашей системой, например асинхронный ввод-вывод или ввод-вывод с аппаратным ускорением, в которых выделенная подсистема управляет всеми сетевыми передачами и отправляет уведомление о завершении в ваше приложение, когда передача завершена. Это позволяет вам использовать свой собственный код управления подключением/мультиплексирования сокетов/чтения-записи, а не использовать средства, предоставляемые cryptlib.

Следующее обсуждение относится к сетевым сокетам, поскольку это наиболее распространенная абстракция, используемая для сетевого ввода-вывода, однако cryptlib будет работать с любым идентификатором сетевого ввода-вывода, который может быть представлен целочисленным значением или дескриптором. Если для абстракции вашей сети требуется нечто большее, чем простой дескриптор, вы можете передать ссылку или индекс массиву любых структур данных, необходимых вашей системе для обработки сетевого ввода-вывода.

В пояснительном тексте говорится, что приложение может использовать это для реализации самого ввода-вывода, а не для того, чтобы cryptlib выполнял ввод-вывод, что мне и нужно. В нем также упоминается, что, хотя примеры программирования касаются сокетов, этот принцип также может быть применен к другим типам ввода-вывода.

Однако все приведенные примеры программирования сводятся к следующему:

 /* Wait for data to arrive */
[Some application defined code that reads data from the network and puts it into an application defined buffer]

/* Read data from the session */
cryptPopData( cryptSession, ... );
 

Я не понимаю, как зашифрованные RxData, полученные кодом приложения, становятся видимыми для cryptlib, чтобы они могли быть обработаны cryptlib (и, если применимо, расшифрованы). Без этого шага как cryptPopData предполагается предоставить мне расшифрованные данные, если я никогда не сообщу им, что я получил с удаленного устройства?

То же самое и с TxData — я не вижу никакого API cryptlib, который предоставляет мне исходящие зашифрованные(1) данные, которые он хотел бы отправить по сети.

Я ожидал бы либо 2 обратных вызова ввода-вывода, предоставляемых приложением (один для чтения и один для записи), ЛИБО дополнительный интерфейс push/pop, который выводит исходящие сетевые данные из cryptlib и отправляет входящие сетевые данные в cryptlib.

(1) Я понимаю, что это было бы более тонко — это также могли бы быть данные для первоначального подтверждения TLS — в этом случае cryptlib потребовал бы, чтобы я отправлял данные без предоставления незашифрованных TxData, и что это потребовало бы, чтобы я получал данные, фактически не получая из них расшифрованную полезную нагрузку RxData.

Комментарии:

1. @MarcoBonelli cryptPopData [предположительно] извлекает обработанные данные из cryptlib и записывает их в предоставленный выходной буфер, чтобы приложение могло их использовать, а не наоборот.

2. Ах, моя беда, соглашение об именах сбило меня с толку.