Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame

Environment: VC6 NT4 IE 4,5

This article covers the basics of selecting a client certificate for use within WinInet. I have put this text together, in the hope it may prevent others suffering the hair loss I have during the last week.

First of all I am assuming you know the basics of setting up a HTTPS connection, bellow is a brief outline to refresh your memory. The INTERNET_FLAG_SECURE flag can be set within the InternetConnect command to force the use of SSL.

    // Initialize wininet.
    hOpen = InternetOpen (...)
    // connect to remote server
    hConnect = InternetConnect ( hOpen, strServerName , ....)

    // Open a HTTP request
    hReq = HttpOpenRequest (hConnect, "GET", strObject, ....)

    // Send request
    HttpSendRequest (hReq, ....)

    // read results
    InternetReadFile (hReq, bBuf, cbBuf, &cbRead)
    // use the returned HTML page

If the server that we are making the request to requires a client certificate then the HttpSendRequest function will fail with the error ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED. At this point we must select a certificate.

There are basically 2 ways of selecting a certificate. First (the easiest, and the way IE does it), is to ask the user. See Dialog bellow.

This can be done programmatically using the following code:-

while ( !HttpSendRequest( hReq, NULL, 0, NULL, 0 ) )
    dwError = GetLastError();
       // Return ERROR_SUCCESS regardless of clicking on OK or Cancel
       if( InternetErrorDlg( GetDesktopWindow(), 
                             FLAGS_ERROR_UI_FILTER_FOR_ERRORS       |
                             FLAGS_ERROR_UI_FLAGS_GENERATE_DATA     |
                             NULL) != ERROR_SUCCESS )
           return ;

See Q224282 for more details.

However if you dont want the user to see the dialog, then you will need to actually select the certificate programmatically. This sounds simple but, due to the extreme lack of documentation becomes something of a nightmare.

Anyhow it can basically be accomplished using InternetSetOptions INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT flag. This, you may notice has no documentation. The sample code for using this flag is included. But the guts of it are here:-

if (!HttpSendRequest (hReq, NULL, 0, NULL, 0) )
        dwError = GetLastError () ;
            //This works but there is no way to iterate through the client certs
            DWORD dwCert = 0;
                              &dwCert, sizeof(dwCert));

           goto again;

This will select the first client certificate registered with WinInet. The bad news is if there are more than one Cert on the machine then you dont know which one you got!

As the most common reason for wanting to avoid the selection dialog is because the application is running as a service, I will provide a link to an MS article that describes how to set the registry up to cope with finding the certs when running as system. Q190542.

I will also include some code I picked up from a news group posting with regards to enumerating the client certificates installed. Although this is inrelated to the article directly, it may prove useful. 

I would also like to thank Scott Davis. For his Dev Studio HTML Plugin.


Download source - 2KB


  • Can you get a realm when doing certificate authentication?

    Posted by sshields on 12/05/2007 06:23am

    When the httpsendrequest fails with ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, is there a way to get the realm? Or does that not apply with certificates? I want to use the realm to associate it with the certificate for future connections.

  • Very nice

    Posted by GuOddian on 12/05/2005 09:14am

    Exactly the information I was looking for.

  • Proxy Authentication Required

    Posted by Legacy on 01/21/2004 08:00am

    Originally posted by: Shan

    Not able to succesfully connect to the server through SSL. Basically I am using your code as it is. The HttpSendRequest() succeeds, but it's handle response is as below.
    ---------------------handle response-----------------------
    "+ response {0x00841951 "
    Proxy Authentication Required
    Unable to complete request:
    Access denied due to authentication failure.
    Could you plese tell me as to what I could be doing wrong?

  • Excellent Information

    Posted by Legacy on 10/21/2003 07:00am

    Originally posted by: Cecilia

    Thank you so much.
    They are very useful information and samples. Information that you won't find in the MSDN. It certainly saves my day.


    Posted by Legacy on 04/16/2003 07:00am

    Originally posted by: Sunglim Lee

    You have indeed saved bunch of my hair!

    Thank you very much for sharing your precious information.

  • Code doesn't work when implemented as DLL

    Posted by Legacy on 01/30/2003 08:00am

    Originally posted by: Juaritos

    I included this code in a VC++ desktop app and works perfect, however, when I migrated this code to an ATL component so it can be called from an ASP page, fails when executing HttpSendRequest and never returns, so I cannot even call GetLastError() to get the error code.

    I tried the same using VB6 but got the same results, ...works well as a dektop app, but HttpSendRequest never returns when the code is included in an ActiveX dll.

    I also tried to do the same using c# in a web service, but .net does not have access to the private key using X509Certificate.

    Any clues on why this code doesn't work when implemented as a component.

  • But how do you register a cert w/WinInet?

    Posted by Legacy on 11/14/2001 08:00am

    Originally posted by: Ken Overton

    That seems, to me, to be the crux of the issue. If we want to install a trusted root and use it, how do we do that?

    -- kov

  • HTTP With SSL

    Posted by Legacy on 09/20/2001 07:00am

    Originally posted by: Venkata Reddy

    Here is the Solution I got working when I use SSL with HTTP.

    In InternetConnect() call use the HTTPS port instead of HTTP default Port


    Then in
    HttpOpenRequest(.., dwFlags) use

    This would work, and when HttpSendRequest() request returns error and GetLAstError() returns ERROR_INTERNET_INVALID_CA because of the invalid certificate, show up the WinInet message box for selection.


  • I am unable to connect to a server through HTTPS

    Posted by Legacy on 09/15/2000 07:00am

    Originally posted by: Jaganathan Rajagopalan

    Hope you can help. I am unable to succesfully connect to the server through SSL. Basically I am using your code as is. The HttpSendRequest() method fails, with the error code ERROR_INTERNET_SECURITY_CHANNEL_ERROR . Could you plese tell me as to what I could be doing wrong?

  • public/private key pair

    Posted by Legacy on 01/25/2000 08:00am

    Originally posted by: G. Vinod Kumar

    How SSL is used with public and private keys pair.
    i.e I want to generate public and private key pair on the server and distribute public key to the clients for encryption. Decryption is done at the server using private key. can you please give me the solution for this.

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date