6 Stimmen

Klärung der Verwendung der Funktion WINHTTP_STATUS_CALLBACK, für SSL-Statuscodes

Ich schreibe einige WinHttp-Code in C. Ich sende Anforderungen über SSL, und um SSL-Fehler zu behandeln, registriere ich eine Funktion WINHTTP_STATUS_CALLBACK über einen Aufruf an WinHttpSetStatusCallback mit dwNotificationFlags auf WINHTTP_CALLBACK_STATUS_SECURE_FAILURE gesetzt.

Die Dokumentation zu WINHTTP_STATUS_CALLBACK besagt, dass beim Aufruf des Callbacks mit dwInternetStatus = WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, bedeutet dies, dass

Beim Abrufen eines SSL-Zertifikats (Secure Sockets Layer) vom Server sind ein oder mehrere Fehler aufgetreten. Der Parameter lpvStatusInformation enthält ein Flag. Weitere Informationen finden Sie in der Beschreibung für lpvStatusInformation.

Nun, die lpvStatusInformation Parameter als LPVOID typisiert ist. Aber ich entnehme dieser Aussage in der Dokumentation, dass er im Falle von WINHTTP_CALLBACK_STATUS_SECURE_FAILURE nicht als Zeiger behandelt wird.

Das Dokument für lpvStatusInformation sagt:

Wenn der Parameter dwInternetStatus den Wert WINHTTP_CALLBACK_STATUS_SECURE_FAILURE hat, kann dieser Parameter einen der folgenden Werte annehmen.

...Und diese Werte sind einer der folgenden Hex-Werte: 1,2,4,8,10,20,40. (Siehe WinHttp.h)

Das scheint mir ziemlich klar zu sein. Ich sollte den Zeiger nicht de-referenzieren, um den Wert zu erhalten. die lpvStatusInformation enthält den hexadezimalen Wert, nicht einen Zeiger.

Verstehe ich das richtig?


Ich habe meinen Code auf diese Weise geschrieben, und es hat in der Vergangenheit funktioniert. Denke ich! Aber jetzt bekomme ich eine lpvStatusInformation von 0x0104f288. Das entspricht keinem dieser Hex-Werte. Es ist auch nicht möglich, diesen Wert durch ODER-Verknüpfung der möglichen Werte zu erzeugen (obwohl die Dokumentation nichts über mehrere Status-Elemente im selben DWORD sagt). Für mich sieht es wie ein Zeiger aus. Und wenn ich den Zeiger de-refere, erhalte ich 0x8, das entspricht WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA was zumindest sinnvoll ist.


Die Frage ist: Soll ich diesen Zeiger de-referenzieren oder nicht?

Hier ist der Rückrufcode:

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);
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X