How do you use WinHTTP to do SSL with a self signed cert

cylus picture cylus · Oct 12, 2013 · Viewed 12.7k times · Source

I seem to be having issues with this, and in the spirit of having a generic question that can be referenced by others, I am looking for a good example of using SSL.

More specifically, I am getting the error 0x00002F8F from WinHttpSendRequest, which is ERROR_INTERNET_DECODING_FAILED (which indicates to me that its a cert error). I have imported the cert on this machine, and am able to pull up the page in IE without a cert error.

The code I am using is here.

TLDR: How do you use WinHTTP with a self signed cert?

Answer

ribram picture ribram · Oct 30, 2013

For WinHTTP, in order to accept/allow SSL validation failures, you must first make the request and allow it to fail, then disable the security checks and retry the operation on the request handle. Something along the lines of:

// Certain circumstances dictate that we may need to loop on WinHttpSendRequest
// hence the do/while
do
{
    retry = false;
    result = NO_ERROR;

    // no retry on success, possible retry on failure
    if(WinHttpSendRequest(
        mHRequest,
        WINHTTP_NO_ADDITIONAL_HEADERS,
        0,
        optionalData,
        optionalLength,
        totalLength,
        NULL
        ) == FALSE)
    {
        result = GetLastError();

        // (1) If you want to allow SSL certificate errors and continue
        // with the connection, you must allow and initial failure and then
        // reset the security flags. From: "HOWTO: Handle Invalid Certificate
        // Authority Error with WinInet"
        // http://support.microsoft.com/default.aspx?scid=kb;EN-US;182888
        if(result == ERROR_WINHTTP_SECURE_FAILURE)
        {
            DWORD dwFlags =
                SECURITY_FLAG_IGNORE_UNKNOWN_CA |
                SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE |
                SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
                SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;

            if(WinHttpSetOption(
                mHRequest,
                WINHTTP_OPTION_SECURITY_FLAGS,
                &dwFlags,
                sizeof(dwFlags)))
            {
                retry = true;
            }
        }
        // (2) Negotiate authorization handshakes may return this error
        // and require multiple attempts
        // http://msdn.microsoft.com/en-us/library/windows/desktop/aa383144%28v=vs.85%29.aspx
        else if(result == ERROR_WINHTTP_RESEND_REQUEST)
        {
            retry = true;
        }
    }
} while(retry);