Уточнить использование функции WINHTTP_STATUS_CALLBACK для кодов состояния SSL - PullRequest
3 голосов
/ 06 января 2011


Я пишу некоторый код WinHttp на C. Я отправляю запросы по SSL, и для обработки ошибок SSL я регистрирую функцию WINHTTP_STATUS_CALLBACK через вызов WinHttpSetStatusCallback с dwNotificationFlags, установленным в WINHTTP_CALLBACK_STATUS_SECURE_FAILURE.

В документации для WINHTTP_STATUS_CALLBACK говорится, что когда обратный вызов вызывается с dwInternetStatus = WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, это указывает, что

Обнаружена одна или несколько ошибок при получении сертификата Secure Sockets Layer (SSL) с сервера. Параметр lpvStatusInformation содержит флаг. Для получения дополнительной информации см. Описание для lpvStatusInformation.

Теперь параметр lpvStatusInformation вводится как LPVOID. Но я беру это из этого утверждения в документации, что он не рассматривается как указатель в случае WINHTTP_CALLBACK_STATUS_SECURE_FAILURE.

Документ для lpvStatusInformation говорит:

Если параметр dwInternetStatus имеет значение WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, этот параметр может принимать одно из следующих значений.

... И эти значения являются одним из этих шестнадцатеричных значений: 1,2,4,8,10,20,40. (См. WinHttp.h)

Это кажется мне довольно понятным. Я не должен отменять ссылку на указатель, чтобы получить значение. lpvStatusInformation содержит шестнадцатеричное значение, а не указатель.

Правильно ли я интерпретирую это?


Я написал свой код таким образом, и он работал в прошлом. Я думаю! Однако теперь я получаю lpvStatusInformation 0x0104f288. Это не похоже ни на одно из этих шестнадцатеричных значений. Также невозможно создать это значение с помощью ИЛИ возможных значений (хотя в документе ничего не сказано о нескольких элементах состояния в одном и том же DWORD). Это выглядит как указатель на меня. И когда я де-реф указатель, я получаю 0x8, что соответствует WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA, что, по крайней мере, имеет смысл.


Вопрос в том, должен ли я отменить ссылку на этот указатель или нет?

Вот код обратного вызова:

void CALLBACK Iirf_WinHttpSslStatusCallback( HINTERNET hInternet,
                                             DWORD_PTR context,
                                             DWORD code,
                                             void * pInfo,
                                             DWORD infoLength)
{
    if (code == WINHTTP_CALLBACK_STATUS_SECURE_FAILURE) {
        ConfigInfo * cfg = (ConfigInfo *) context; // app-specific structure
        DWORD details = (DWORD) pInfo; // do not de-reference??
        CHAR buffer[32];
        CHAR * statusDescription = NULL;

        switch (details) {
            case WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED:
                statusDescription = "CERT_REV_FAILED";
                break;

            case WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT:
                statusDescription = "INVALID_CERT";
                break;

            case WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED:
                statusDescription = "CERT_REVOKED";
                break;

            case WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA:
                statusDescription = "INVALID_CA";
                break;

            case WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID:
                statusDescription = "CERT_CN_INVALID";
                break;

            case WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID:
                statusDescription = "CERT_DATE_INVALID";
                break;

            case WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR:
                statusDescription = "SECURITY_CHANNEL_ERROR";
                break;

            default:
                statusDescription = buffer;
                sprintf_s(buffer, 32, "stat(0x%08X) len(%d)",
                          details, infoLength);
                break;
        }

        LogMessage(cfg, 1, "SslStatusCallback: %s", statusDescription);
    }
}

1 Ответ

6 голосов
/ 18 июня 2011

Документы немного вводят в заблуждение.lpvStatusInformation - указатель на значение флагов.Мы приводим его к DWORD * и разыменовываем его, а полученные значения совпадают со значениями флагов в документах.

...