C でいくつかの WinHttp コードを書いています。SSL 経由でリクエストを送信しています。SSL エラーを処理するために、dwNotificationFlags を WINHTTP_CALLBACK_STATUS_SECURE_FAILURE に設定して WinHttpSetStatusCallbackを呼び出して、WINHTTP_STATUS_CALLBACK 関数を登録しています。
WINHTTP_STATUS_CALLBACK のドキュメントによると、コールバックがdwInternetStatus
= WINHTTP_CALLBACK_STATUS_SECURE_FAILURE で呼び出されると、それは
サーバーから SSL (Secure Sockets Layer) 証明書を取得中に、1 つ以上のエラーが発生しました。lpvStatusInformation パラメータにはフラグが含まれています。詳細については、lpvStatusInformation の説明を参照してください。
現在、lpvStatusInformation
パラメーターは LPVOID として入力されています。しかし、ドキュメントのそのステートメントから、WINHTTP_CALLBACK_STATUS_SECURE_FAILURE の場合はポインターとして扱われないことが分かります。
のドキュメントは次のようにlpvStatusInformation
述べています。
dwInternetStatus パラメータが WINHTTP_CALLBACK_STATUS_SECURE_FAILURE の場合、このパラメータは次のいずれかの値になります。
...そして、これらの値は 16 進値の 1 つです: 1、2、4、8、10、20、40。(WinHttp.h を参照)
これは私にはかなり明確に思えます。値を取得するためにポインターを逆参照するべきではありません。これ lpvStatusInformation
は、ポインターではなく、16 進値を保持します。
これを正しく解釈していますか?
私はそのようにコードを書きましたが、過去には機能していました。おもう!しかし今、私はlpvStatusInformation
0x0104f288 を取得しています。これは、これらの 16 進値とはまったく異なります。また、可能な値を OR してその値を作成することもできません (ドキュメントには、同じ 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);
}
}