Я пытаюсь в https связаться с сервером, используя WinInet (из Win32 API).
Вот очень минималистский код:
HINTERNET ses = InternetOpenA("test",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0) ;
HINTERNET con = InternetConnectA(ses,"stackoverflow.com",INTERNET_DEFAULT_HTTPS_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,0,NULL) ;
HINTERNET req = HttpOpenRequestA(con,"GET",NULL,NULL,NULL,NULL,INTERNET_FLAG_SECURE,NULL) ;
HttpSendRequestA(req,NULL,0,NULL,0) ;
DWORD read ;
char str[3000] ;
InternetReadFile(req,reinterpret_cast<void*>(str),sizeof(str)-1,&read);
str[read] = 0 ;
cout << &str[0] << endl ;
Пока я общаюсь с "классическим" https-сервером, таким как stackoverflow.com , все идет хорошо. Проблема заключается в том, что я пытаюсь связаться с сервером, который запрашивает аутентификацию клиента.
У меня есть 3 файла .pem: сертификат и закрытый ключ для моего клиента, а также корневой сертификат, который аутентифицирует мой клиентский сертификат (т.е. цепочка сертификатов длиной 2).
Для информации, я могу подключить свой сервер с помощью командной строки cULR:
curl https://my.server --cert Client_cert.pem --key Client_key.pem --cacert Root_cert.pem
Это доказательство того, что это возможно!
Читая документацию по WinInet, я обнаружил страницу с именем «Обработка аутентификации», но все дело в имени пользователя: пароле, а в сертификате ничего нет.
Я обнаружил, что должен использовать библиотеку Crypt32: я создаю контекст сертификата с CertCreateCertificateContext (используя двоичные данные из client_cert.pem ), а затем передаю его с помощью InternetSetOptionA . Но тогда HttpSendRequestA завершается с ошибкой 12157 ...
Я должен признать, что был бы рад найти хороший учебник или пример кода! Кстати, я не имею ни малейшего понятия о том, как вставить свой закрытый ключ в эти вещи ...
Заранее спасибо!