tags:

views:

1482

answers:

4

I'm working on a simple little function to download a file from an SSL-enabled website using the WinInet functions, namely InternetOpen and InternetOpenURL. I had was initially failing the call to InternetOpenURL with a ERROR_INTERNET_INVALID_CA (12045) because I was using a self-signed certificate on my test server, and found out (http://support.microsoft.com/kb/q182888/) that the fix seemed to be to use the InternetQueryOption/InternetSetOption combination to pass various flags to INTERNET_OPTION_SECURITY_FLAGS option. Now, however, InternetQueryOption fails with a ERROR_INTERNET_INCORRECT_HANDLE (12018) response from GetLastError(). Any ideas why this would be the case? I'm using the handle that came directly from InternetOpen, which previously worked fine with a non-SSL InternetOpenURL. Shouldn't this be the correct handle?

I don't have the actual code (different computer), but it is very similar to the following, and fails on InternetGetOption with ERROR_INTERNET_INCORRECT_HANDLE:

  HINTERNET hReq = InternetOpen(...)
  if (!hReq) { printf("InternetOpen Error: %d", GetLastError()); }

  DWORD dwFlags = 0;
  DWORD dwBuffLen = sizeof(dwFlags);
  BOOL ret = false;

  ret = InternetQueryOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,
                            (LPVOID)&dwFlags, &dwBuffLen);
  if (!ret) { printf("InternetQueryOption Error: %d", GetLastError()); }

  dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
  ret = InternetSetOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,
                          &dwFlags, sizeof (dwFlags) );
  if (!ret) { printf("InternetSetOption Error: %d", GetLastError()); }

  InternetOpenURL(hReq, ...)
A: 

I see you're not checking the hReq you get back from InternetOpen. Perhaps that is the root of your problem. See what this tells you if you add it right after the call to InternetOpen:

if (hReq == NULL) {
    printf("InternetOpen Error: %d", GetLastError());
}
bdumitriu
I've done that, just (accidentally) elided for brevity and edited the original question to include the sample. Also, I can use this exact same HINTERNET handle (hReq) with InternetOpenURL to download a file from a non-SSL URL, which seems to indicate that its a good handle.
A: 

I've done that, just (accidentally) elided for brevity. So here would be the entire code "sample":

  HINTERNET hReq = InternetOpen(...)
  if (!hReq) { printf("InternetOpen Error: %d", GetLastError()); }

  DWORD dwFlags = 0;
  DWORD dwBuffLen = sizeof(dwFlags);
  BOOL ret = false;

  InternetQueryOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,
                      (LPVOID)&dwFlags, &dwBuffLen);
  if (!ret) { printf("InternetGetOption Error: %d", GetLastError()); }

  dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
  ret = InternetSetOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,
                          &dwFlags, sizeof (dwFlags) );
  if (!ret) { printf("InternetSetOption Error: %d", GetLastError()); }

  InternetOpenURL(hReq, ...)

Also, I can use this exact same HINTERNET handle (hReq) with InternetOpenURL to download a file from a non-SSL webserver (i.e. using straight HTTP), which seems to indicate that its a good handle. Is my use or understanding of InternetQueryOption invalid?

+1  A: 

From the MSDN docs for INTERNET_OPTION_SECURITY_FLAGS:

Be aware that the data retrieved this way relates to a transaction that has occurred, whose security level can no longer be changed.

No transaction has occurred on your handle yet. InternetOpen gives you the root HINTERNET handle. This could apply to a HTTP, FTP or Gopher connection - whereas the security options are fairly specific to HTTPS and largely also dependent on what the remote server supports. As such, you're asking Wininet for information that it can't give you.

Jon Bright
A: 

I used to receive similar error. I then passed the handle returned by a HttpOpenRequest(...) to InternetQueryOption and it worked just fine. Try it out.