Search code examples
cwinapiwininetinternetsetoption

How to use InternetSetOption to ignore self signed certificates


I can't seem to figure out how to use InternetSetOption()

In Setting and Retrieving Internet Options, the example is using new INTERNET_PER_CONN_OPTION[3]; to allocate space for the INTERNET_PER_CONN_OPTION structs, but as far as I know C does not have a new keyword, so I tried to do it like below. Although this does not cause any errors, it does not fix the problem of making a request to a self-signed website.

int request(char * host, int port,char * endpoint, char * data, size_t dlen )
{
    LPCSTR accept[] = {"*/*", NULL};
    char  hdrs[] = "Content-Type: application/json";
    HINTERNET hConnect, hSession, hRequest;
    hSession = InternetOpen("",
                            INTERNET_OPEN_TYPE_PRECONFIG,
                            NULL,
                            NULL,
                            0);
    INTERNET_PER_CONN_OPTION_LIST list;
    INTERNET_PER_CONN_OPTION ops[1];
    DWORD   dwBufSize = sizeof(list);
    list.dwSize = sizeof(list);
    list.pszConnection = NULL;
    list.dwOptionCount = 1;
    list.pOptions = ops;
    list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
    list.pOptions[0].Value.dwValue = SECURITY_FLAG_IGNORE_UNKNOWN_CA ;
    hConnect = InternetConnect(hSession,
                                host,
                                port,
                                NULL,
                                NULL,
                                INTERNET_SERVICE_HTTP,0,1);
    hRequest = HttpOpenRequest(hConnect,
                                "GET", 
                                endpoint,
                                _T("HTTP/1.1"),
                                NULL,
                                accept,
                                INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_SECURE,1);
    if (!InternetSetOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &list, dwBufSize))
        printf("Failed to set options Error: %ld\n", GetLastError());
    if (hRequest == NULL)
        printf("Error: %ld\n", GetLastError());
    if (HttpSendRequest(hRequest, hdrs, strlen(hdrs), data, dlen))
    {
        DWORD received;
        char tmp[MAX_LEN];
        while (InternetReadFile(hRequest, tmp, MAX_LEN, &received) && received)   
            printf("%s\n", tmp);
    }
    return 0;
}

How does one use InternetSetOption() to set the SECURITY_FLAG_IGNORE_UNKNOWN_CA?


Solution

  • You are using InternetSetOption in the wrong way, A quick internet search will yeild lots of examples but here is how to use it in your case

    int request(char * host, int port,char * endpoint, char * data, size_t dlen )
    {
        LPCSTR accept[] = {"*/*", NULL};
        char  hdrs[] = "Content-Type: application/json";
        HINTERNET hConnect, hSession, hRequest;
        DWORD dwFlags;
        DWORD dwBuffLen = sizeof(dwFlags);
        hSession = InternetOpen("",
                                INTERNET_OPEN_TYPE_DIRECT,
                                NULL,
                                NULL,
                                0);
    
        hConnect = InternetConnect(hSession,
                                    host,
                                    port,
                                    NULL,
                                    NULL,
                                    INTERNET_SERVICE_HTTP,0,1);
        hRequest = HttpOpenRequest(hConnect,
                                    "GET", 
                                    endpoint,
                                    _T("HTTP/1.1"),
                                    NULL,
                                    accept,
                                    INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_SECURE,1);
        if (!InternetSetOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, dwBuffLen))
            printf("Failed to set options Error: %ld\n", GetLastError());
        if (hRequest == NULL)
            printf("Error: %ld\n", GetLastError());
        if (InternetQueryOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, &dwBuffLen))
        {
            dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_CERT_CN_INVALID|SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
            InternetSetOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags));
        }
        if (HttpSendRequest(hRequest, hdrs, strlen(hdrs), data, dlen))
        {
            DWORD received;
            char tmp[MAX_LEN];
            while (InternetReadFile(hRequest, tmp, MAX_LEN, &received) && received)   
                printf("%s\n", tmp);
        }
        return 0;
    }
    

    It is also worth paying attention to the parameters of InternetSetOption from the documentation