Пример реализации драйвера шифрования сетевых пакетов
В качестве основы драйвера, шифрующего сетевые пакеты, может быть использован пример промежуточного драйвера ImSamp с сервера Microsoft (для NT 4.0) или промежуточный драйвер Passthru из DDK (NtDDK\src\network\ ndis\passthru, для Win2000). Этот NDIS-драйвер промежуточного уровня разработан так, чтобы располагаться между транспортным драйвером и драйвером сетевой карты (рис. 30). Единственное что он делает – это получает пакеты от драйвера сетевой карты и передает их драйверу транспорта, и наоборот.
Используя Network Control Panel Application (NCPA), можно привязать протокол TCP/IP к виртуальному адаптеру, создаваемому драйвером ImSamp, а все остальные привязки заблокировать. Для драйвера ТСР/IP промежуточный драйвер ImSamp выглядит как драйвер виртуальной сетевой карты. А для реальной сетевой карты Ethernet драйвер ImSamp выглядит как драйвер протокола.
Если разрабатываемый драйвер шифрования не реализует функции сетевого уровня модели OSI, то его нельзя будет использоваться в сети, где в качестве средств построения объединенных сетей используются маршрутизаторы, работающие на сетевом уровне. Так как такой драйвер не рассчитан на то, что выпущенный зашифрованный пакет может быть фрагментирован, поэтому его можно использовать только в сегменте сети до маршрутизаторов.
Рис. 30. Расположение драйвера шифрования
Как уже отмечалось выше, спецификация NDIS позволяет добавлять заголовки (или хвост) к NDIS-пакету без необходимости его перекопирования, во время передачи пакета по стеку сетевых драйверов. Таким образом, промежуточный драйвер шифрования может зашифровать пакеты двумя способами:
- Путем модификации исходного NDIS-пакета, переданного драйвером транспорта, с добавлением к нему (при необходимости) новых NDIS – буферов.
- Путем создания собственного NDIS-пакета копированием в него исходного NDIS-пакета, переданного драйвером транспорта, а затем уже модификации собственного пакета.
Первый способ использовать не рекомендуется, так как он чреват ошибками из-за использования библиотекой NDIS зарезервированных областей в пакете (при этом они будут перезаписываться). Но в простейших случаях этот способ работает.
При реализации первого способа важно помнить, что после завершения операции отправки зашифрованного пакета в сеть, в функции ProtocolSendComplete перед возвращением описателя пакета драйверу транспорта необходимо преобразовать пакет в исходное состояние. То есть расшифровать его и отделить все добавленные NDIS-буфера.
Драйвер может осуществлять зашифрование всех данных пакета, кроме Ethernet и IP-заголовков, IP-заголовок, при этом, можно создать свой, а первоначальный зашифровать.
Ключ шифрования обычно передается в драйвер шифрования из кода пользовательского режима (библиотеки DLL или приложения) с помощью вызова функции DeviceloControl. Обмен ключами между компьютерами можно, например, осуществить по схеме ISAKMP/Oakley, реализовав приложение (или библиотеку DLL), использующее интерфейс API WinSocket.
Если зашифрованный пакет имеет длину большую, чем первоначальный пакет, то для того, чтобы драйвер протокола не мог послать пакет такой длиной, что после добавления к нему необходимого числа байт промежуточным драйвером, драйвер сетевой карты (или сама сетевая карта) обрезал бы его (например, если длина преобразованного пакета вместе с Ethernet заголовком – 1514 байт), то при обработке запроса от драйвера протокола на максимально возможную длину пакета, значение, которое в действительности получено от драйвера сетевой карты, уменьшается на необходимое число байт.