3

I have my desktop application. I would like to send post request to server URL using mutual authentication in C#. I have written following code:

System::Net::ServicePointManager::SecurityProtocol = SecurityProtocolType::Tls12;
WebRequestHandler ^ clientHandler = gcnew WebRequestHandler();
X509Certificates::X509Certificate2^ modCert = gcnew X509Certificates::X509Certificate2("Dev.pfx", "test");
clientHandler->ClientCertificates->Add(cerInter);
clientHandler->AuthenticationLevel = System::Net::Security::AuthenticationLevel::MutualAuthRequested;
clientHandler->ClientCertificateOptions = ClientCertificateOption::Manual;
httpClient = gcnew HttpClient(clientHandler);
HttpContent ^ httpContent = gcnew ByteArrayContent(state->postBody);
httpContent->Headers->ContentType = gcnew MediaTypeHeaderValue("application/octet-stream");
resultTask = httpClient->PostAsync(state->httpRequest, httpContent);

Now post request is throwing exception that it is connection is forcefully closed by remote host. I have used wireshark and it shows that client certificate in client response is of zero length. Even if I don't add any certificate in WebRequestHandler, I get the same response. Can someone please help me to solve this issue or guide me for possible solutions.

Screenshot for wireshark

EDIT

Hi All, I have found the issue. I have to set client certificate in local store.

X509Certificates::X509Store store(X509Certificates::StoreName::Root, X509Certificates::StoreLocation::LocalMachine);
store.Ostore. Openrtificates::OpenFlags::ReadWrite);
store. Add(cerInter); 

However, I am facing the issue that if I don't run my application as administrator, then it throws access right exception.

If I use StoreLocation::CurrentUser, it pop up message for approval.

Can someone please suggests, how can I Use it with StoreLocation::CurrentUser without prompting the message?

Besides it, I will really appreciate if someone can suggests, if this is the right approach?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
bulunga
  • 51
  • 1
  • 12
  • One more information - I have not added any web.config file. I dont know if it would be required for desktop application ? – bulunga Jun 19 '17 at 15:28
  • The code in your example is Managed C++, not C#? – EricLaw Jun 19 '17 at 16:36
  • Hi Eric, thanks for your prompt answer. Yes, it is but all classes I have used from C# only. – bulunga Jun 19 '17 at 18:07
  • I'm not sure what you mean by this. If the Managed C++ code above is not the code you're having trouble with, can you share the code you are having trouble with? – EricLaw Jun 19 '17 at 20:09
  • Hi Eric, I am really sorry if I have confused you.... it is managed C++ code which was bothering me. My thought was that HTTPclient and WebRequestHandler all are part of System.Net.HTTP. So if some body will advice me some example in C#, I can easily write relevant code in Managed C++... – bulunga Jun 20 '17 at 02:59

1 Answers1

3

By Windows' design, you cannot add certificates to the per-user store without a prompt. You can add certificates to the Local Machine store, but only when running with Administrative rights.

You should only need to add the certificate to the user's store once (e.g. during first run or setup).

EricLaw
  • 56,563
  • 7
  • 151
  • 196
  • Thanks Eric for clarification. I need one suggestion / confirmation from you. Is it mandatory to set certificate in store for mutual authentication ? Can we not direct server to look certificates added in WebRequestHandler (which is part of httpclient in my example) ? – bulunga Jun 19 '17 at 18:09
  • I'm not sure. It's /possible/ that SChannel (the component which handles HTTPS handshakes) requires that the certificate be installed in the current user's trust store (e.g. see the Fiddler configuration instructions: http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/RespondWithClientCert) so that the private key is available at the right time, but this seems like a pretty lame limitation. If that ("Does a cert in WebRequest.ClientCertificates have to be installed to a trust store first?") is the answer you're looking for, it may be helpful to make the question more explicit. – EricLaw Jun 19 '17 at 20:19
  • Hi Eric, My apology for confusing question. Let me rephrase my question - I am getting the certificate from another component. So it is not in disk. Now for SSL handshake, when I call X509.Store, it saves it in local system's disk. Is there any way to avoid to save it in disk ? I have tried to set both certificates in httpclient object but server ignores that while doing handshake. Is there any possible way to ask server to dont look in X509Store(which is on disk) but look in httpclient object ? – bulunga Jun 20 '17 at 03:08