Just partially fixed my problem.
Turns out that it is because I'm using ASP.Net and its not adding the client certificates. If I run it as a console application the certificate is passed through correctly. Does anyone know how to get this working in ASP.Net now or of any workarounds for ASP.Net? Regards, Michael Lyons From: ozdotnet-boun...@ozdotnet.com [mailto:ozdotnet-boun...@ozdotnet.com] On Behalf Of Michael Lyons Sent: Thursday, 8 April 2010 12:11 PM To: 'ozDotNet' Subject: RE: HttpWebRequest and client certificates over HTTPS Shane, I'm not trying to upload a client certificate, its part of the authentication processes of the web service (xml / REST). I have to send client certificates around due to the API I am dealing with. It's unfortunately not my choice and the API is controlled by a 3rd party. The process is a two way authentication process which verifies the server and the client are who they say they are and are speaking over an encrypted channel. Regards, Michael Lyons From: ozdotnet-boun...@ozdotnet.com [mailto:ozdotnet-boun...@ozdotnet.com] On Behalf Of Shane Nall Sent: Thursday, 8 April 2010 10:08 AM To: ozDotNet Subject: Re: HttpWebRequest and client certificates over HTTPS Hi Michael, Your email raises a few questions like why are you sending certs around, and what do really want to achieve? But first I can answer the upload question... because I'm assuming because you're using POST you want to upload from a client to a web server. On the server side you need to host a page to upload to... you can use an aspx page and in the Page_Load use Request and the HttpPostedFile class. eg. Code... protected void Page_Load(object sender, EventArgs e) { try { StringBuilder sb = new StringBuilder(); string folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Uploads"); // Ensure the folder exists Directory.CreateDirectory(folder); foreach (string filename in Request.Files.AllKeys) { HttpPostedFile file = Request.Files[filename]; file.SaveAs(Path.Combine(folder, file.FileName)); sb.AppendLine("Uploaded: " + file.FileName); } Response.Write(sb.ToString()); } catch (Exception ex) { Response.Write(ex.ToString()); } } On the client side you need to look at the System.Net.WebClient class and the UploadFile method. eg. Code... WebClient client = new WebClient(); client.Credentials = CredentialCache.DefaultNetworkCredentials; //HACK: byte[] respBytes = client.UploadFile(uploadUrl, "POST", filename); string response = Encoding.UTF8.GetString(respBytes); On 8 April 2010 08:26, Michael Lyons <maill...@ittworx.com> wrote: I need to send a client certificate over HTTPS to a URL to authenticate against some data which I am POSTing. It seems like I just can't get the client certificate to be sent over the channel. This is the code I'm using, it's been hacked a fair bit to just try to get it working. ---------- pathToCertificate = "C:\blah\blah\mycertificate.cer"; System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(requestUri); webRequest.Method = "POST"; webRequest.ContentLength = contentLength; webRequest.ContentType = contentType; if (requestData != null && contentLength > 0) { webRequest.GetRequestStream().Write(requestData, 0, contentLength); } if (clientCertificates.Count > 0) { webRequest.Credentials = CredentialCache.DefaultCredentials; webRequest.PreAuthenticate = true; webRequest.ClientCertificates.Add(new X509Certificate2(pathToCertificate)); System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; // **** Always accept }; } System.Net.HttpWebResponse webResponse = (System.Net.HttpWebResponse)webRequest.GetResponse(); --------------- Using Fiddler it looks like it doesn't send the client certificate! This is what Fiddler outputs: CONNECT http://<endpoint>:443 HTTP/1.1 Host: <endpoint> Proxy-Connection: Keep-Alive HTTP/1.1 200 DecryptTunnel Established Timestamp: 18:32:34:7696 FiddlerGateway: Direct This is a HTTPS CONNECT Tunnel. Secure traffic flows through this connection. Secure Protocol: Tls Cipher: Rc4 128bits Hash Algorithm: Md5 128bits Key Exchange: RsaKeyX 1024bits == Client Certificate ========== None. == Server Certificate ========== <Removed from email> POST https://<endpoint> HTTP/1.1 Content-Type: application/x-www-form-urlencoded Host: <endpoint> Content-Length: 129 Expect: 100-continue <MyPostData> HTTP/1.0 403 Forbidden Server: <EndServer>/1.1 Connection: Keep-Alive Content-Length: 33 Error 403: Missing authentication HELP! Regards, Michael Lyons -- Cheers, Shane DISCLAIMER NOTICE The contents of this email are confidential. If you are not the intended recipient, you must not disclose, copy or use the contents in anyway. If you have received this email in error, please delete it and notify us by reply email. It is the recipient's responsibility to screen this message and any attachments for computer viruses. Thank you.