Развернуть все
Свернуть все

Рекомендации по использованию API SADB

API SADB

Управление ключами и данными протокола IPsec в вычислительной среде кластера (отдельного компьютера) обеспечивается средствами базы данных. В задачи базы данных входит:

  • обеспечение обмена и хранения ключей протокола в защищённом виде

  • обеспечение собственной ключевой системы

Система защиты ключей протокола определяется ассоциацией безопасности базы данных, задающей алгоритмы защиты ключей и их параметры. В дальнейшем комплекс управления ключами протокола IPsec и управления ключами базы данных будем обозначать SADB. Построение комплекса SADB осуществляется на базе API SADB.

Клиенты 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(<новый ключ>)

Для всех элементов IPsec SA SADB выполняем операции:
  • 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