HOWTO: Select Client Certificate in WinInet

ID: Q224282


The information in this article applies to:
  • Microsoft Internet Explorer (Programming) versions 4.0, 4.01, 4.01 SP1, 4.01 SP2, 5.0


SUMMARY

This article explains how to select a client certificate using the WinInet APIs.


MORE INFORMATION

When accessing any SSL protected resource on a Web server that requires a valid client certificate, the WinInet HttpSendRequest API or MFC CInternetFile::SendRequest will fail initially with the following error:

ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED (12044)
To correctly handle this error, you can call InternetErrorDlg to bring up the client certificate dialog box (similar to the one in Internet Explorer) for the user to select the certificate. The code sample is shown as follows:

...
while ( !HttpSendRequest( hReq, NULL, 0, NULL, 0 ) )
{
    dwError = GetLastError();
    if ( dwError == ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED )
    {
       // Return ERROR_SUCCESS regardless of clicking on OK or Cancel
       if( InternetErrorDlg( GetDesktopWindow(), 
                             hReq,
                             ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED,
                             FLAGS_ERROR_UI_FILTER_FOR_ERRORS       |
                             FLAGS_ERROR_UI_FLAGS_GENERATE_DATA     |
                             FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, 
                             NULL) != ERROR_SUCCESS )
       {
           return ;
       }
    }
}
... 
The same idea applies to MFC WinInet. In the case of MFC WinInet classes, the MFC methods corresponding to the WinInet APIs above are as follows:
  • CInternetFile::SendRequest


  • CInternetFile::ErrorDlg


Notes

  • To set client certificate, InternetErrorDlg has to be called after HttpSendRequest fails with the error ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED (12044).


  • InternetErrorDlg always returns ERROR_SUCCESS regardless of whether you click OK or Cancel.


  • Currently it is not supported to use the InternetSetOption API with the option flag of INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT to select a particular client certificate. The result is unpredictable if the client has more than one client certificate on the machine. Developers who want to select a client certificate programmatically without the UI should write a WinSock application using SSPI to do SSL.


Because InternetErrorDlg always returns ERROR_SUCCESS, it may be tricky to determine if user clicked Cancel.

If Cancel is clicked, then certificate won't be sent. If OK is clicked, the certificate will be sent.

If the client certificate is not sent but server requires it, error HTTP status code will be returned. The status code will be 403. You can get it like this:

if ( !HttpQueryInfo (hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL))
{
   // Handle Error Here
} 
Receiving 403 on the second retry of HttpSendRequest after InternetErrorDlg was called can indicate that user clicked Cancel.


REFERENCES

For information on how to handle invalid server certificate authority error with WinInet, please see the following article in the Microsoft Knowledge Base:

Q182888 Handle Invalid Certificate Authority Error with WinInet

Additional query words:

Keywords : kbIE400 kbIE401 kbIE401sp1 kbIE401sp2 kbIE500
Version : WINDOWS:4.0,4.01,4.01 SP1,4.01 SP2,5.0
Platform : WINDOWS
Issue type : kbhowto


Last Reviewed: May 20, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.