четверг, 22 ноября 2012 г.

Проблема в wininet

Проблема: во время обращение к HTTPS-серверу через WinInet выясняется, что серверный сертификат отозван (ERROR_INTERNET_SEC_CERT_REV_FAILED)  или неверен (ERROR_INTERNET_INVALID_CA) или истек (ERROR_INTERNET_SEC_CERT_DATE_INVALID). Как правильно проигнорировать эти ошибки и продолжить обработку запроса?

Решение: необходимо отправить запрос, посмотреть GetLastError(), после чего поправить флаги соединения и отправить запрос еще раз. Видимо такая архитектура сделана для пущей безопасности, но это самая жуткий протокол взаимодействия подсистем, который я когда-либо видел. Флаги, которые нужно проставить для игнорирования ошибок:

  • ERROR_INTERNET_SEC_CERT_REV_FAILED - SECURITY_FLAG_IGNORE_REVOCATION
  • ERROR_INTERNET_INVALID_CA - SECURITY_FLAG_IGNORE_UNKNOWN_CA
  • ERROR_INTERNET_SEC_CERT_DATE_INVALID - SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Код:

BOOL bRepeat = FALSE;
int sendResult = 0;
do{
bRepeat = FALSE;
sendResult =  HttpSendRequest(hRequest, lpszHeaders, dwHeadersLength, lpOptional, dwOptionalLength);
if (!sendResult){
int lastErr = GetLastError();
if (lastErr == ERROR_INTERNET_INVALID_CA) {
WARNING("Серверный сертификат недействителен");
DWORD dwFlags;
DWORD dwBuffLen = sizeof(dwFlags);
InternetQueryOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS,(LPVOID)&dwFlags, &dwBuffLen);
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
InternetSetOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) );
bRepeat = TRUE;
}else if (lastErr==ERROR_INTERNET_SEC_CERT_REV_FAILED){
WARNING("Серверный сертификат отозван");
// аналогично SECURITY_FLAG_IGNORE_REVOCATION
bRepeat = TRUE;
}else if (lastErr==ERROR_INTERNET_SEC_CERT_DATE_INVALID){
WARNING("Серверный сертификат ИСТЕК");
// аналогично SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
bRepeat = TRUE;
}else{
MLASTERROR
ERROR("Не удалось отправить веб-запрос");
}
}
}while(bRepeat);
return sendResult;




Комментариев нет:

Отправить комментарий