Client Certificate Validation

M

Matt Frame

I am working on a special ASP.Net application that receives files from
customers. The connection is made via HTTPS and the client sends the file
as a POST to my ASP.Net listener. All of this works fine. Now I am looking
at how to validate the clients certificate programmatically. The client
application sends to me with something like:
....
Dim myHttp As HttpWebRequest =
CType(WebRequest.Create(https://myserver/Receive.aspx), HttpWebRequest)
myHttp.Timeout = 300000
myHttp.KeepAlive = True
myHttp.ContentLength = PostData.Length
myHttp.UserAgent = "Mozilla/4.0 (compatible; MSIE 4.01; Windows NT)"
myHttp.Method = "POST"
myHttp.AllowAutoRedirect = True

'-- Cert Stuff
Dim cert As X509Certificate =
X509Certificate.CreateFromCertFile("d:\temp\cert\ProdCert.cer")
myHttp.ClientCertificates.Add(cert)

Dim tmpStream As Stream
Try
tmpStream = myHttp.GetRequestStream()
Catch ex As WebException
End Try

tmpStream.Write(PostData, 0, PostData.Length)
tmpStream.Flush()
tmpStream.Close()
....

This process seems to work fine, but then I perform a
Request.ClientCertificate in my Receive.aspx nothing is there. In my
Receive.aspx page I have the following code:

Dim cert as HttpClientCertificate

cert = Request.ClientCertificate

Nothing comes across or at least doesn't seem to populate the
ClientCertificate object. If I use the above client to send data to
another system that is Java based they say the client certificate is there.
Can Java do something that .Net can't?

I hope someone can shed some light into why the client certificate is not
showing up in the ClientCertficate object as I am really hoping to keep this
project small by staying in the same language environment.

Thanks,

Matt
 
S

Steve Jansen

Matt,

Sounds like a webserver config issue. Is your IIS application setup to
accept or require client certificates? Do you use 1-1 or 1-many certificate
mapping to log the user on? Is the certificate issued by a CA trusted by
the IIS LocalSystem (i.e., computer) account. In other words, is the CA
cert installed in the "Certificates (Local Computer)\Trusted Root
Certificate Authorities\Certificates" certificate store?

You might want to check out the Patterns & Practices doc "How To: Set Up
Client Certificates (.NET Framework Security)"

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT17.asp

-Steve Jansen
 
M

Matt Frame

Steve,

My IIS settings are set to require encryption and require client
certificate. I think you are misunderstanding what I am doing. This
application does not use browsers in any way and I am not using the system
to log a user into our server. My client uses WebMethods and they require
that I receive their certificate on the POST and validate it against the
same certificate I put into my certificate store but I need to be able to
get to the client certificate on their POST for other reasons and that is
why I am expecting to get it with Request.ClientCertificate.

The problem may be that I am sending and receiving on the same development
workstation but I would assume that the certificate would be returned from
the call to Request.ClientCertificate any time.

Thanks,

Matt
 
S

Steve Jansen

Hi Matt,

Sorry for the confusion, but, I do think I understand what you are trying to
do, as I have worked with the exact same scenario.

IIS treats all HTTP clients equally, whether they are a browser or a simple
telnet client issuing HTTP request headers on port 80. So, the IIS
configuration was worth bringing up. It sounds like you have everything
configured correctly.

It is interesting that you are using a single machine for testing. I
believe I saw this problem before with using localhost, in that the CN of
the SSL certificate does not match the server name. You may want to check
out
http://msdn.microsoft.com/library/d...mationservicesiis.asp?frame=true&hidetoc=true,
which instructs you to either use the .NET 1.1 config setting:

<system.net>
<settings>
<servicePointManager
checkCertificateName="true"
/>
</settings>
</system.net>

or create a class that implements ICertificatePolicy and returns true in a
name mismatch scenario. It would interesting to know if this solves your
problem on the client:
....
System.Net.ServicePointManager.CertificatePolicy = new MyPolicy();
....
public class MyPolicy : ICertificatePolicy {
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate
certificate, WebRequest request, int certificateProblem) {
return true; // always return true for testing
// Check for policy common name mismatch.
/* if (certificateProblem == 0 || certificateProblem == 0x800c010f)
return true;
else
return false;
*/
}
}

-Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top