Hi,
For a client I'm developing a proxy class in C# for easy communication with a web service that's hosted on a Resin web server, which apparently is a Java/Unix environment.
For authentication with the web service I need to pass my client certificate with every request I make and that's were the trouble starts
I requested a client certificate from COMODO which I installed on my local machine. I exported this certificate to a p12 file with a private key.
To make myself known on the web server I had to upload a pem file to the web server so I used openssl to convert my p12 file to a pem file with a pass phrase and uploaded this to server which got accepted, contrary to my p12 file.
The manual of the web service supplies a code example making use of curl. I have to post three parameters and a xml file to a specified URL. My code looks as follows:
curl -E clientcertificate.pem:p4ssphr4se -F parameter1=xxx -F parameter2=xxx -F parameter3=xxx -F xml=@test.xml https://test.xxx/action/batchUpload
This code works like a charm.
Now I have to convert this curl command to C# code. I'm using a HttpClient object with a handler with a certificate. I can't use a pem-file in my C# code so I'm using the p12 file.
//try to create client certificate from settings
var clientCertificatePath = appSettings[SETTING_KEY_CLIENT_CERTIFICATE_PATH];
var clientCertificatePrivateKey = appSettings[SETTING_KEY_CLIENT_CERTIFICATE_PRIVATE_KEY];
//create certificate from file
_clientCertificate = new X509Certificate2(System.Web.HttpContext.Current.Server.MapPath(clientCertificatePath), clientCertificatePrivateKey);
WebRequestHandler handler = new WebRequestHandler();
handler.ClientCertificates.Add(_clientCertificate);
_httpClient = new HttpClient(handler);
var testFilePath = System.Web.HttpContext.Current.Server.MapPath(@"~\test.xml");
using (var form = new MultipartFormDataContent())
{
form.Add(new StringContent("xxx"), "parameter1");
form.Add(new StringContent("xxx"), "parameter2");
form.Add(new StringContent("xxx"), "parameter3");
var fileData = File.ReadAllBytes(testFilePath);
var byteArrayContent = new ByteArrayContent(fileData, 0, fileData.Count());
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
form.Add(byteArrayContent, "xml", "test.xml");
var response = _httpClient.PostAsync("https://test.xxx/action/batchUpload", form).Result;
using (HttpContent content = response.Content)
{
// ... Read the string.
Task<string> result = content.ReadAsStringAsync();
var res = result.Result;
System.Web.HttpContext.Current.Response.Write(res);
}
}
Now the problem I'm facing...
If I run this code, my request seems to be authenticated ok, because if I don't use a certificate I receive a nice 403-response. But I add the certificate like in the code I'm receiving a 500-response.
I compared the POST request I make with one I make with curl using Fiddler and the 100% the same the only difference is that in C# is use the p12-file and with curl I use the pem-file.
So for me it seems the problem is with the file format of the client certificate I use. I read a lot about the different formats and for me it's quit confusing but I understood that p12 files ar used on Windows based systems and pem files are used on Unix/Linux
based systems. And I'm thinking the problem might has something to do with this...
Any help would be much appreciated!