I am writing client for mutual-tls communication in C# (actually clr / cli). I am facing issue while doing it. When I am running it.
I have written a following code in my post method:--
System::Net::ServicePointManager::SecurityProtocol = SecurityProtocolType::Tls12;
HttpClient^ httpClient;
Task<HttpResponseMessage ^> ^ resultTask;
WebRequestHandler ^ clientHandler = gcnew WebRequestHandler();
clientHandler->ClientCertificates->Add(state->ptrClientCert);//add certificate of client provided by server
clientHandler->AuthenticationLevel = System::Net::Security::AuthenticationLevel::MutualAuthRequired;
httpClient = gcnew HttpClient(clientHandler);
httpClient->DefaultRequestHeaders->Accept->Add("application/octet-stream");
HttpContent ^ httpContent = gcnew ByteArrayContent(state->postBody);
httpContent->Headers->ContentType = gcnew MediaTypeHeaderValue("application/octet-stream");
resultTask = httpClient->PostAsync(state->httpRequest, httpContent);
if (resultTask->Wait(DefaultTimeOut))
//wait for finish
{
HttpResponseMessage ^ response = resultTask->Result;
SetResponse(response, state->darkClientRef, state->ptrHttprequest, state->appLog);
}
Now this code is not working as it is throwing socket exception that " Unable to read data from the transport connection: An existing connection was forcefully closed by remote host connection". My understanding says, that possible reason can be that I am not able to set my private key in request as client certificate provided by server only has public key.
Now my question is that how can I set my private key (which is in PKCS8 format) in this request ?
I am using .Net framework 4.5.2.
EDIT:
After my research, I have found that issue is, I am not setting my private key in my X509Certificate. I am receiving private key from different component. As per my understanding, the following way would be right way to set private key.
WebRequestHandler ^ clientHandler = gcnew WebRequestHandler();
X509Certificates::X509Certificate2^ modCert = gcnew X509Certificates::X509Certificate2(state->ptrClientCert);
RSACryptoServiceProvider ^ rsaProvider;
rsaProvider = RSAConverter::DecodePrivateKeyInfo(privateKey);
modCert->PrivateKey = rsaProvider;
clientHandler->ClientCertificates->Add(modCert);
I have implemented DecodePrivateKeyInfo function using following links :--
http://www.jensign.com/opensslkey/opensslkey.cs
But this function fails to parse my private key (which is created by openssl) as it fails in CompareBytearrays function. Can somebody help me that how can I set this PKCS8 format key in X509 certificate ?