Проблема: во время обращение к HTTPS-серверу через WinInet выясняется, что серверный сертификат отозван (ERROR_INTERNET_SEC_CERT_REV_FAILED) или неверен (ERROR_INTERNET_INVALID_CA) или истек (ERROR_INTERNET_SEC_CERT_DATE_INVALID). Как правильно проигнорировать эти ошибки и продолжить обработку запроса?
Решение: необходимо отправить запрос, посмотреть GetLastError(), после чего поправить флаги соединения и отправить запрос еще раз. Видимо такая архитектура сделана для пущей безопасности, но это самая жуткий протокол взаимодействия подсистем, который я когда-либо видел. Флаги, которые нужно проставить для игнорирования ошибок:
Решение: необходимо отправить запрос, посмотреть 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;
Чтобы не умереть от тоски: Сведения: коды ошибок WinInet (с 12001 по 12156), Как обрабатывать недопустимые ошибка WinInet сертификата центра
Комментариев нет:
Отправить комментарий