API SADB
Управление ключами и данными протокола IPsec в вычислительной среде кластера (отдельного компьютера) обеспечивается средствами базы данных. В задачи базы данных входит:
-
обеспечение обмена и хранения ключей протокола в защищённом виде
-
обеспечение собственной ключевой системы
Клиенты SADB и схемы обмена ключами и данными протокола IPsec.
Клиентами обмена ключами и данными протокола IPsec могут быть:-
сессия фазы 1 протокола IKE (прикладной уровень)
-
сессия фазы 2 протокола IKE (прикладной уровень)
-
SADB - сессия базы данных (прикладной уровень)
-
сессии ESP/AH - процесса уровня ядра
Между клиентами производятся обмены информацией следующих типов:
-
обмен между различными объектами фазы 1 осуществляется транспортным представлением структуры SADBIKESA
-
обмен между различными объектами фазы 2 осуществляется транспортным представлением структуры SADBIPSECSA
-
обмен между объектами фазы 2 и ESP/AH осуществляется транспортным представлением структуры SADBIPSECSA
Ключевая система SADB
Ключевая система SADB включает закрытые и открытые ключи администраторов клиентов SADB и ключи обмена. В случае кластера закрытые ключи клиентов прикладного уровня могут совпадать с единственным ключом администратора кластера.Виды закрытых ключей:
-
ключ на базе PSK
-
ключ из ключевого контейнера, хранящегося на устройстве долговременной внешней памяти
-
эфемерный ключ
В API SADB пользовательский ключ представляется структурой PRIVKEY, подготовка и сопровождение даннй структуры (создание ключей, уничтожение ключей, смена ключей) осуществляется приложением SADB. Открытый ключ, соответствующий закрытому ключу, представляется структурой SADBSA. Клиенты SADB, обменивающиеся информацией, также должны обменяться открытыми ключами. Обмен открытыми ключами осуществляется приложением SADB. В случае кластера с единым ключом все клиенты прикладного уровня имеют единый открытый ключ. Во внутреннем обмене клиент использует представление открытого ключа структурой PUBKEY.
Ключ обмена вырабатывается функциями API SADB из закрытого ключа клиента-отправителя информации, открытого ключа клиента-получателя и UKM, передаваемого в составе структуры данных.
Алгоритмы и параметры SADB
Алгоритм выработки закрытого ключа из PSKЗакрытый ключ SADB получается из PSK хешированием ASCII представления HEX-кода PSK. Длина представления - 34 байта. Параметры алгоритма выработки закрытого ключа из PSK:
-
CPIKE_HASH_A = 65501, // id-GostR3411-94-CryptoProParamSet
Алгоритм выработки ключа обмена
Ключ обмена вырабатывается по алгоритму 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, PRIVKEY и под транспортное представление структур.
Сценарии работы 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 |
создание данных для инициализации программного ДСЧ
Copy Code | |
---|---|
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.
Copy Code | |
---|---|
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 |