How To Select Client Certificate in WinInet (224282)



The information in this article applies to:

  • Microsoft Internet Explorer (Programming) 4.0
  • Microsoft Internet Explorer (Programming) 4.01
  • Microsoft Internet Explorer (Programming) 4.01 SP1
  • Microsoft Internet Explorer (Programming) 4.01 SP2
  • Microsoft Internet Explorer (Programming) 5
  • Microsoft Internet Explorer (Programming) 5.01
  • Microsoft Internet Explorer (Programming) 5.5
  • Microsoft Internet Information Services 5.0

This article was previously published under Q224282

SUMMARY

This article explains how you can select a client certificate by using the WinInet APIs.

MORE INFORMATION

When you are accessing any Secure Socket Layer (SSL)-protected resource on a Web server that requires a valid client certificate, the WinInet HttpSendRequest API or Microsoft Foundation Classed (MFC) CInternetFile::SendRequest fails and the following error message appears:
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 must be called after HttpSendRequest fails with the error ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED (12044).
  • InternetErrorDlg always returns ERROR_SUCCESS for ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED regardless of whether you click OK or Cancel.
  • The INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT option to select a particular client certificate is not supported and should not be used. The result is unpredictable if the client has more than one client certificate on the computer. On Internet Explorer 5.01 and earlier, it is not possible to select a client certificate programmatically (without using the user interface). Developers who insist on doing it should write a WinSock application using the Security Support Provider Interface (SSPI) to do SSL.
  • Internet Explorer 5.5 has a new option that allows you to select client certificate programmatically, INTERNET_OPTION_CLIENT_CERT_CONTEXT. When you use this option with InternetSetOption, (LPVOID) lpBuffer parameter should point to CERT_CONTEXT structure.

    You can obtain CERT_CONTEXT structure by using Win32 Crypto APIs, such as CertEnumCertificatesInStore() or CertFindCertificateInStore().
Because InternetErrorDlg always returns ERROR_SUCCESS, it may be tricky to determine if the user clicked Cancel.

If Cancel is clicked, then a certificate is not sent. If OK is clicked, the certificate is sent.

If the client certificate is not sent but the server requires it, the server will return the 403 HTTP status code. You can query the status code by using the following code:
if ( !HttpQueryInfo (hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL))
{
   // Handle Error Here
}
				
If Cancel is clicked, you will receive error 403 on the second retry of HttpSenRequest after InternetErrorDlg was called.

REFERENCES

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

182888 Handle Invalid Certificate Authority Error with WinInet


Modification Type:MinorLast Reviewed:7/13/2004
Keywords:kbhowto KB224282