API SADB
Управление ключами и данными протокола IPsec в вычислительной среде кластера (отдельного компьютера) обеспечивается средствами базы данных. В задачи базы данных входит:
-
обеспечение обмена и хранения ключей протокола в защищённом виде
-
обеспечение собственной ключевой системы
Клиенты SADB и схемы обмена ключами и данными протокола IPsec.
Клиентами обмена ключами и данными протокола IPsec могут быть:-
сессия фазы 1 протокола IKE (прикладной уровень)
-
сессия фазы 2 протокола IKE (прикладной уровень)
-
SADB - сессия базы данных (прикладной уровень)
-
сессии ESP/AH - процесса уровня ядра
Между клиентами производятся обмены информацией следующих типов:
-
обмен между различными объектами фазы 1 осуществляется транспортным представлением структуры SADBIKESA
-
обмен между различными объектами фазы 2 осуществляется транспортным представлением структуры SADBIPSECSA
-
обмен между объектами фазы 2 и ESP/AH осуществляется транспортным представлением структуры SADBIPSECSA
Ключевая система SADB
Ключевая система SADB включает закрытые и открытые ключи администраторов клиентов SADB и ключи обмена. В случае кластера закрытые ключи клиентов прикладного уровня могут совпадать с единственным ключом администратора узла сети.Виды закрытых ключей:
-
ключ из ключевого контейнера, хранящегося на устройстве долговременной внешней памяти
-
эфемерный ключ
В API SADB закрытый ключ представляется структурой PRIVKEY. Создание, уничтожение, смена ключей осуществляется приложением SADB. Открытые ключи, соответствующие закрытым ключам, управляются приложением SADB. Клиент использует представление открытого ключа в виде структуры PUBKEY_2012. Клиенты SADB, обменивающиеся информацией, также должны обменяться открытыми ключами. Для целей обмена клиенты используют представление открытого ключа в составе структуры SADB_PUBLICKEYBLOB.
Все клиенты прикладного уровня используют единый ключ администратора и единую структуру PRIVKEY. Для процесса ядра необходимо создать собственные ключи и собственные структуры PRIVKEY.
Ключ обмена вырабатывается функциями API SADB из закрытого ключа клиента-отправителя информации, открытого ключа клиента-получателя и UKM, передаваемого в составе структуры данных.
Алгоритмы и параметры SADB
Алгоритм выработки ключа обменаКлюч обмена вырабатывается по алгоритму VKO GOST R 34.10-2001 (п. 5.2. RFC 4357). Параметры алгоритма выработки ключа обмена:
-
CPIKE_HASH_A = 65501, // id-GostR3411-94-CryptoProParamSet
-
CPIKE_GROUP_XchA = 65509, // id-GostR3410-2001-CryptoPro-XchA-ParamSet
Алгоритмы экспорта/импорта ключей IKE и SPI
Экспорт/импорт ключей IKE и SPI осуществляется по алгоритму GOST 28147-89 Key Wrap, GOST 28147-89 Key Unwrap (пп. 6.1, 6.2. RFC 4357). Параметры алгоритмов экспорта/импорта ключей IKE и SPI:
-
CPIKE_ENC_A = 65502, // id-Gost28147-89-CryptoPro-A-ParamSet
Состав API SADB
Функции SADBФункции CreateEphemFn, deSerializePubKeyFn, DestroyPrivKeyFn, DestroyPubKeyFn используются как на прикладном уровне, так и на уровне ядра ОС.
Функции CreateProvFn и CreatePSKFn используются на прикладном уровне.
Функции API SADB не осуществляют выделения памяти под объекты. Приложение SADB должно обеспечить выделение памяти под структуры PRIVKEY, PUBKEY_2012 и под транспортное представление структур.
Сценарии работы SADB. Подготовка закрытых ключей приложением SADB
Перед началом работы с клиентом приложение SADB должно создать контекст провайдера и установить пароль ключа на контекст.
-
CryptAcquireContext(&hProv, pszContanerName, ..., PROV_GOST_2001_DH, 0)
-
CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, PIN, 0)
При использовании PSK необходимо создать контекст провайдера вызовом:
-
CryptAcquireContext(&hProv, NULL, ..., PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT)
На уровне ядра должны быть определены hModule, hProv вызовами:
-
CPCCreateProvider(&hModule, pConfig)
-
CPCAcquireContext(hModule, &hProv, NULL, CRYPT_VERIFYCONTEXT, pVTable)
В случае кластера все клиенты прикладного уровня используют единый ключ администратора узла сети и единую структуру PRIVKEY. Для процесса ядра необходимо создать собственные ключи и собственные структуры PRIVKEY.
Сценарии работы SADB. Последовательность вызовов при инициализации
Последовательность при загрузке шлюза
User space | Kernel |
---|---|
создание данных для инициализации программного ДСЧ | инициализация программного ДСЧ |
sadb.CreateProvFn или sadb.CreatePSKFn - создание PRIVKEY и сериализованного PubKey sadb.deSerializePubKeyFn - десериализация ESP PubKey |
sadb.deSerializePubKeyFn - десериализация IKE PubKey sadb.CreateEphemFn - создание PRIVKEY и сериализованного PubKey |
создание данных для инициализации программного ДСЧ
DWORD dwDatalen; HCRYPTPROV hProv; BYTE *data; CryptAcquireContext(&hProv, 0, 0, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT); CryptGetProvParam(hProv, PP_RANDOM, 0, &dwDatalen, 0); data = malloc(dwDatalen); CryptGetProvParam(hProv, PP_RANDOM, data, &dwDatalen, 0); CryptReleaseContext(hProv, 0);
инициализация программного ДСЧ
Входные данные data, PRNG_data_length.
BYTE *data - указатель на данные DWORD PRNG_data_length - длина данных HCRYPTMODULE hModule; HCRYPTPROV hProv; DWORD dwDatalen; BYTE *data; CPCCreateProvider(&hModule, pConfig); hModule->AcquireContext(hModule, &hProv, NULL, CRYPT_VERIFYCONTEXT); dwDataLen = 0; hModule->GetProvParam(hModule, hProv, PP_RANDOM, NULL, &dwDataLen, 0); if(dwDataLen != PRNG_data_length) { ошибка длины данных; } CRYPT_DATA_BLOB CBlob; CBlob.cbData = dwDataLen; CBlob.pbData = data; hModule->SetProvParam(hModule, hProv, PP_RANDOM, (BYTE*)&CBlob, 0); hModule->ReleaseContext(hModule, hProv, 0);
Сценарии работы SADB. Рестарт vpnd
User space | Kernel |
---|---|
sadb.DestroyPubKeyFn(IKE_PubKey) | |
sadb.DestroyPubKeyFn(ESP_PubKey) sadb.DestroyPubFn (IKE_hpsadb) sadb.DestroyKeyFn (IKE_hsadb) cpike_shutdown_gost рестарт cpike_init_gost ike_init_espFn - игнорируем буфер инициализатор ДСЧ sadb.CreateProvFn или sadb.CreatePSKFn sadb.deSerializeFn |
sadb.deSerializeFn Возвращаем ранее созданную SADB SA sadb.deSerializeFn |
Сценарии работы SADB. Смена ключа модуля ядра.
Останавливаемся, а потом получаем открытый ключ SADB от модуля ядра.
User space | Kernel |
---|---|
sadb.CreateEphemFn | |
sadb.deSerializeFn sadb.DestroyPubFn ESP_hpsadb = ESP_hpsadb_new |
sadb. DestroyKeyFn ESP_hsadb = ESP_hsadb_new |
Сценарии работы SADB. Cмена ключа vpnd.
Для всех элементов IKE SA SADB выполняем операции:
-
p1_deSerializeFn(<старый ключ>)
-
p1_SerializeFn(<новый ключ>)
-
spireSerializeFn(<старый ключ>, <открытый новый>)
-
spireSerializeFn(<новый ключ>, <открытый новый>)
После этих действий, все узлы кластера выполняют сценарий:
User space | Kernel |
---|---|
sadb.DestroyPubFn (ESP_hpsadb) sadb.DestroyPubFn (IKE_hpsadb) sadb.DestroyKeyFn (IKE_hsadb) sadbCreateProvFn или sadbCreatePSKFn sadb.deSerializeFn |
|
sadb.DestroyPubFn (IKE_hpsadb) sadb.deSerializeFn Возвращаем ранее созданную SADB SA |
|
sadb.deSerializeFn |