Работа с пакетами безопасности Windows |
При разработке модуля КриптоПро TLS учитывалась существующая в операционной системе Windows архитектура пакетов безопасности. В соответствии с этой архитектурой протоколы защищенного обмена реализуются через специфицированный Microsoft интерфейс - Security Service Provider Interface (SSPI) (См. http://msdn.microsoft.com/library/en-us/security/security/sspi.asp).
В соответствии с существующей в операционной системе Windows архитектуре использования пакетов безопасности модуль КриптоПро TLS возможно использовать как в стандартном программном обеспечении Microsoft, так и встраивать в разрабатываемое прикладное программное обеспечение.
Кроме использования протокола TLS в интерфейсе Internet Explorer, прикладное программное обеспечение может использовать протокол TLS для аутентификации и защиты данных, передаваемых по собственным протоколам на основе TCP/IP и HTTPS.
Примеры встраивания имеются в тестовом ПО разработки ООО "Крипто-Про" (http://www.cryptopro.ru/CryptoPro/test/sample.zip и http://www.cryptopro.ru/CryptoPro/product14.html, файлы WebClient.c, WebServer.c, tls.c), а также в составе Microsoft Platform SDK (\Samples\WinBase\Security\SSL).
Производится загрузка библиотеки Secur32.dll, Security.dll при работе с операционными системами Windows NT 4.0, Windows 2000, Windows ХР; библиотеки schannel.dll - при работе с операционными системами Windows 95, Windows 95 OSR2, Windows 98, Windows 98 SE, Windows ME.
С помощью функции GetProcAddress получается указатель на функцию InitSecurityInterfaceA (InitSecurityInterfaceW в случае компиляции с Unicode).
Вызовом функции InitSecurityInterfaceA (InitSecurityInterfaceW в случае компиляции с Unicode) получается таблица функций SSPI.
Заполняется структура SCHANNEL_CRED. Поля этой структуры должны быть нулевыми, кроме:
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION; SchannelCred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION;Для сервера и не анонимного клиента заполняются также поля:
SchannelCred.cCreds = 1; SchannelCred.paCred = &pCertContext.
Примечание. Контекст сертификата pCertContext должен содержать ссылку на секретный ключ.
Производится вызов функции создания Credentials: AcquireCredentialsHandle с передачей ей структуры SCHANNEL_CRED и имени пакета - UNISP_NAME ("Microsoft Unified Security Protocol Provider").
Инициализация соединения клиентом производится вызовом InitializeSecurityContext без входного буфера и сервером - вызовом AcceptSecurityContext, после чего идет обычный цикл Handshake.
После установления соединения, но до начала передачи данных, приложение должно выполнить проверку параметров соединения и сертификата удаленной стороны.
Для получения сертификата удаленной стороны вызывается функция QueryContextAttributes с аргументом SECPKG_ATTR_REMOTE_CERT_CONTEXT.
Для построения цепочки сертификатов рекомендуется использование функции CertGetCertificateChain, описанную в MSDN/Platform SDK/Security, (с флагами проверки, соответствующими выбранному уровню безопасности. Рекомендуется использовать флаг CERT_CHAIN_CACHE_END_CERT | CERT_CHAIN_REVOCATION_CHECK_CHAIN.
Цепочка сертификатов проверяется функцией CertVerifyCertificateChainPolicy, описанной там же, с аргументом pszPolicy, равным OIDCERT_CHAIN_POLICY_SSL, и аргументом pPolicyPara, заполненным следующим образом:
ZeroMemory(&polHttps, sizeof(HTTPSPolicyCallbackData)); polHttps.cbStruct = sizeof(HTTPSPolicyCallbackData); polHttps.dwAuthType = AUTHTYPE_SERVER; polHttps.fdwChecks = 0; polHttps.pwszServerName = pwszServerName; memset(&PolicyPara, 0, sizeof(PolicyPara)); PolicyPara.cbSize = sizeof(PolicyPara); PolicyPara.pvExtraPolicyPara = &polHttps;Необходимо, чтобы для каждого сертификата в цепочке pCertContext->pCertInfo->SubjectPublickeyInfo->Algoritm->pszObjId заканчивалась на szOID_GR3410.
Вызывается функция QueryContextAttributes с аргументом ulAttribute, равным SECPKG_ATTR_CONNECTION_INFO, для получения параметров соединения и их проверки на выполнение условий:
ConnectionInfo.dwProtocol == SP_PROT_TLS1_CLIENT ConnectionInfo.aiCipher == CALG_G28147 ConnectionInfo.aiHash == CALG_GR3411 ConnectionInfo.aiExch == CALG_DH_EX_EPHEM || ConnectionInfo.aiExch == CALG_DH_EX_SF || ConnectionInfo.aiExch == CALG_DH_EL_EPHEM || ConnectionInfo.aiExch == CALG_DH_EL_SFЦикл шифрования/рас Для получения параметров соединения шифрования данных реализуется с помощью функций EncryptMessage/DecryptMessage.
Примечание. Должна быть обеспечена корректная обработка кодов возврата функций SSPI. При этом следует учитывать, что требуется разная обработка в зависимости от того, является код возврата кодом успешного выполнения функции, кодом не фатальной ошибки, не требующей разрыва соединения, кодом фатальной ошибки, требующей разрыва соединения. Все необрабатываемые коды возврата ошибок должны приводить к разрыву соединения.