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.

Reply via email to