how to https Certification

Sep 11, 2014 at 1:09 PM
I need a connection to a server with https and have two ".pem files". One for the certificate and one for the key. How can i include these files into my program? Without certification my code works fine. Example:
http_client_config client_config;
web_proxy wp(U("https://myProxy"));
client_config.set_proxy(wp);
http_client client(L"https://httpbin.org/post", client_config);

http_response resp = client.request(methods::POST,L"",L"This is the random text that I wish to send").get();

auto body = resp.extract_string().get();
std::wcout << body;
getch();
But i dont know how i can integrate the certification files. I hope that someone can help.
Coordinator
Sep 15, 2014 at 3:39 PM
Hi ZarakiKen,

The C++ Rest SDK doesn't have any high level API support for setting up and handling certificates. We do have functionality for dropping down to the API we built on top of, using the http_client_config::set_nativehandle_options(...) API. This would not be cross platform. We haven't implemented it yet on all the platforms. What platforms are you running on?

Thanks,
Steve
Sep 19, 2014 at 2:04 PM
Hi stevetgates,

Thank you for the quick answer. Only Windows 7 is used for this project. Can you show me some example how I can handle the certificates?
Coordinator
Sep 19, 2014 at 2:55 PM
Hi ZarakiKen,

I don't have an example off hand but I recommend you take a look at the WinHTTP documentation for SSL. I think it has some examples with certificates. I believe you are going to need to call WinHttpSetOption using WINHTTP_OPTION_CLIENT_CERT_CONTEXT.

Steve
Dec 16, 2014 at 10:16 PM
Hello,
I have a similar requirement where I need to pass both credentials and a certificate to a web service. Using the http_client_config::credentials() seems straight forward enough. But I am having a trouble getting http_client_config::set_nativeHandle_options() to work with WinHTTPSetOption(). One issue I an having is setting the a hRequest to a useful value since I want to prepopulate the certificate context prior to making a request.
is there any chance either of you two might have an example of working code for passing client certificate?
Thank you
Kyle
Coordinator
Dec 17, 2014 at 2:11 AM
Hi Kyle,

I don't have any code examples setting the client certificate.

I don't understand what you mean by 'setting the hRequest to a useful value'? Are you referring to the native_handle parameter type passed to the callback you register with http_client_config::set_nativehandle_options(...)? You don't change this value you use it to pass to WinHTTPSetOption adjusting whatever properties you want changed.

Steve
Dec 17, 2014 at 9:36 PM
Hi Steve,
Thank you for the quick response. I am relatively new to C++ and only have a basic understanding of callbacks. If we put the hRequest question to the side for now and concentrate on the proper use of set_nativehandle_options I might be able to answer a few of my own questions. Right now I am stuck on trying to make a call to set_nativehandle_options. If we expand on the example above, I’ll show my current (non – working) approach to attempt to set the client SSL.
http_client_config client_config;
web_proxy wp(U("https://myProxy"));
client_config.set_proxy(wp);
const std::function<void(native_handle)> AddCertToConfig = &AddCertToClientConfig;
client_config.set_nativehandle_options(AddCertToConfig);
http_client client(L"https://httpbin.org/post", client_config);

http_response resp = client.request(methods::POST,L"",L"This is the random text that I wish to send").get();

auto body = resp.extract_string().get();
std::wcout << body;
getch();
I have the function setup as such:
void AddCertToClientConfig()
{
    HCERTSTORE hMyStore = CertOpenSystemStore(0, TEXT("MY"));
    LPWSTR szCertName = L"foo.cloudapp.net";
    PCCERT_CONTEXT pCertContext = NULL;
    HINTERNET  hRequest = NULL;
    if (hMyStore)
    {
        if (pCertContext = CertFindCertificateInStore(hMyStore,
            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
            0,
            CERT_FIND_SUBJECT_STR,
            szCertName, //Subject string in the certificate.
            NULL))
        {
            printf("The desired certificate was found. \n");
        }

        if (pCertContext)
        {
            WinHttpSetOption(hRequest, 
                WINHTTP_OPTION_CLIENT_CERT_CONTEXT, 
                (LPVOID)pCertContext,
                sizeof(CERT_CONTEXT));
            CertFreeCertificateContext(pCertContext);
        }
        CertCloseStore(hMyStore, 0);
    }
}

I know I am missing something simple, I just don't know what. I get a compiler error of C2197 : 'void (__cdecl *const )(void)' : too many arguments for call. The research I did on this issue appears to relate to a pointer type conflict. But I have not been able to nail down the solution. I am compiling for x86 and x64, and the error is the same in both versions. Here are few links I found on the error.
http://support.microsoft.com/kb/117428
http://www.experts-exchange.com/Programming/System/Q_21521264.html
Coordinator
Dec 18, 2014 at 12:02 AM
Hi Kyle,

The problem is the http_client_config::set_nativehandle_options function takes a std::function that takes a parameter and you are not supplying one. Specifically for Windows desktop it takes a HINTERNET handle. Here is a trivial example that should help you out:
#include <Windows.h>
#include <winhttp.h>
#include <cpprest\http_client.h>

using namespace web;
using namespace web::http;
using namespace web::http::client;

int _tmain(int argc, _TCHAR* argv[])
{
    http_client_config config;
    config.set_nativehandle_options([](HINTERNET requestHandle)
    {
        printf("In set native handle options.\n");
    });
    http_client client(U("http://www.bing.com"), config);

    auto response = client.request(methods::GET).get();
    response.content_ready().wait();

    return 0;
}
Steve