Client certificate support

Oct 8, 2014 at 12:47 AM
Hi,

I am able to add this feature in the windows implementation using this:
#if ( (defined(_WIN32) || defined(WIN32)) && !defined(__cplusplus_winrt) )
  void ClientCerts(const wstring& cert = L"MY", const wstring& subject = wstring())
  {
    /*
      client_cfg is of type web::http::client::http_client_config and available here.
    */
    client_cfg.set_nativehandle_options([&](web::http::client::native_handle handle)->void
    {
      HCERTSTORE hMyStore = 0;
      PCCERT_CONTEXT pCertContext = 0;
      try
      {
        hMyStore = CertOpenSystemStoreW(0, cert.c_str());
        if ( !hMyStore )
          throw "Cannot open the cert store";
        if ( !subject.empty() )
          pCertContext = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
                                                    CERT_FIND_SUBJECT_STR, subject.c_str(), NULL);
        else 
          pCertContext = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, 0, NULL);
        if ( !pCertContext )
          throw "Cannot find a valid cert!";
        if ( !WinHttpSetOption(handle, WINHTTP_OPTION_CLIENT_CERT_CONTEXT,
          (bpvoid)pCertContext, sizeof(CERT_CONTEXT)) )
          throw "WinHttpSetOption failed";
        CertFreeCertificateContext(pCertContext);   CertCloseStore(hMyStore, 0);
      }
      catch (...)
      {
        if ( pCertContext )
          CertFreeCertificateContext(pCertContext);
        if ( hMyStore )
          CertCloseStore(hMyStore, 0);
      }
    });
  } // ClientCerts 
#endif
This is a Windows only solution. Does anyone know how to do this in Linux?
Thanks,
G.
Coordinator
Oct 8, 2014 at 5:12 PM
Hi G,

Right now this won't be possible on Linux. Basically we haven't implemented the set_nativehandle_options feature for all the platforms yet. This definitely is important to allow for customization our public API doesn't support, like what you are doing with client certificates. We have a feature request open tracking this, that you can vote on here.

While we certainly will be adding the set_nativehandle_options support on other platforms, we are not currently working on it so I can't give you an exact time as to when it would be available yet. Once implemented you would have to use OpenSSL/Boost.ASIO to accomplish what you are doing here on Windows.

Steve
Oct 8, 2014 at 11:52 PM
Hi Steve,

Thanks for this clarification.

Another question about web::credentials: I am able to use code like this for client authentication:
      web::http::client::http_client_config client_cfg;
      client_cfg.set_credentials(web::credentials(L"user", L"pass"));
This works ok in Windows but fails in Linux so I had to fall back on creating the authentication header manually. I think I have the latest version, is this suppose to work using web::credentials?

Thanks,

G.
Coordinator
Oct 9, 2014 at 4:33 PM
Hi G,

The behavior you are seeing is accurate, we don't have high level authentication support on all the platforms. Here is a feature request for it. Like you discovered depending on the type of authentication used you can just as easily do it by manually creating the authentication header.

Steve