X.509 Certificate based authentication

G

gudujarlson

I want to use X.509 certificates to authenticate and then subsequently
authorize HTTP requests between a Windows Forms client and a ASP.NET
server. So far I have accomplished all of the following:

- created and installed a server certificate
- setup a virtual directory to require client certificates
- created a ASP.NET web form that displays information about the
client certificate
- created and installed a client certificate
- created a Windows Form application that looks up and passes the
client certificate in a HTTP request to the server

Here's the guts of my client:

Dim aRequest As System.Net.HttpWebRequest =
CType(System.Net.WebRequest.Create("https://localhost/ssl/
default.aspx"), System.Net.HttpWebRequest)
aRequest.ClientCertificates.Add(certificate)

Here's the guts of my web form:

Dim cs As HttpClientCertificate = Request.ClientCertificate
Response.Write("Certificate = " & cs.Certificate.ToString() &
"<br>")

All is working well. The cert gets passed over the wire and the
server can read its contents. Now what?

How do I authenticate the client?

How to I use information from the certificate to identify the client?
In other forms of authentication there is user identifier. What is
the analogy with X.509 certificates? My first guess was that the
"subject" property is the identifier, but I'm not sure that is correct
because it does not appear to be globally unique. For example, the
subject of my client cerificate is "localhost". I'm guessing I am not
the only person on the planet with the same subject. How do I verify
that the client is the _right_ "localhost"?

How do I validate that the certificate was sent to me by it's owner?

Does calling System.Net.HttpWebRequest.ClientCertificates.Add() cause
the HTTP request to be signed or does it simple cause the certificate
to be passed in the request?

Does IIS do anything with the certificate or does it just pass it
through the web form? I.e. does it perform any sort of validation/
authentication?

All help will be greatly appreciated.
 
J

Joe Kaplan

Basically, you need to go by subject and issuer. The assumption is that
the issuer of a certificate will guarantee the uniqueness of the subjects
that it issues and you can restrict the list of issuers that you will accept
certificates from.

It is also possible that you can use certificate mapping in IIS to map
client cert users to Windows users and do your security processing, although
that might not be feasible.

You have to assume that if a user successfully does client cert
authentication with you, only that user has the private key for that
certificate. It is basically equivalent to a user's password, so if someone
else has the private key, they are essentially that user as well.

HTH,

Joe K.
 
G

gudujarlson

Basically, you need to go by subject and issuer. The assumption is that
the issuer of a certificate will guarantee the uniqueness of the subjects
that it issues and you can restrict the list of issuers that you will accept
certificates from.

Thanks for your response. If the subject is guaranteed to be unique,
how do you explain the subject of "localhost" I obtained from a
commercial CA? Is it because subject is not unique on 30-day
evaluation certificates? Is it documented anywhere that subject is
unique? Should I look for such a guarantee on the CA's website? I've
looked around a couple websites and I have not found such a
guarantee. Why does makecert.exe allow me to create certificates with
non-unique subjects? I'm not saying you're wrong. I'm just wondering
why this fact is not stated very clearly somewhere.
It is also possible that you can use certificate mapping in IIS to map
client cert users to Windows users and do your security processing, although
that might not be feasible.

Do you know how this works? Does IIS map the public key to a windows
user? The subject? Something else? How does IIS identify a
certificate uniquely?
You have to assume that if a user successfully does client cert
authentication with you, only that user has the private key for that
certificate. It is basically equivalent to a user's password, so if someone
else has the private key, they are essentially that user as well.

What you say makes common sense to me, however an experiment I did
does not support this. I exported my client certificate without the
private key and then passed the public-key-only certificate along with
my HTTPS call (System.Net.HttpWebRequest.ClientCertificates.Add). IIS
accepted the certificate and mapped it to a windows user ID. I
expected it to not accept it since the caller did not have the private
key. One guess is that the .NET framework looked up the private key
in the cert store even though I did not pass it in.
 
D

Dominick Baier

Basically, you need to go by subject and issuer. The assumption is
that the issuer of a certificate will guarantee the uniqueness of the
subjects that it issues and you can restrict the list of issuers that
you will accept certificates from.

i would not recommend that - either use the thumbprint (which changes when
renewing a cert) - or better use the subject key identifier.
 
J

Joe Kaplan

I guess what I was trying to suggest is that you need to map the key
(thumbprint, subject key identifier, raw public key) to some sort of an
identity. That's the purpose of the certificate. You can either maintain a
table of your own that maps the key to a specific user or you go by some
data in the certificate like the subject name or subject alternative name.
Otherwise you don't really have a way to know who is associated with the
key.

How would you approach this?

Joe K.
 
J

Joe Kaplan

Inline below

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
On May 22, 10:13 am, "Joe Kaplan"

Thanks for your response. If the subject is guaranteed to be unique,
how do you explain the subject of "localhost" I obtained from a
commercial CA? Is it because subject is not unique on 30-day
evaluation certificates? Is it documented anywhere that subject is
unique? Should I look for such a guarantee on the CA's website? I've
looked around a couple websites and I have not found such a
guarantee. Why does makecert.exe allow me to create certificates with
non-unique subjects? I'm not saying you're wrong. I'm just wondering
why this fact is not stated very clearly somewhere.

I guess I should say that it is not typical for a CA to issue a client
certificate with a duplicate name, but I suppose it could happen. Like
Dominick said in his other post, the only thing that is guaranteed to be
unique is the public key, so that or the thumbprint or subject key
identifier would need to be used to tell different certs with the same
subject apart. What I should have said was that the subject (or the subject
alternative name) is the only thing you get from the cert that gives you any
identity information about "who" owns the private key for the cert's public
key.
Do you know how this works? Does IIS map the public key to a windows
user? The subject? Something else? How does IIS identify a
certificate uniquely?

IIS has some flexibility in how it does this as you can create your own
mappings in IIS to control this. At the AD level, the cert can contain an
alternate name with the user's AD UPN in it or the AD user object might have
the cert's subject set up as an alternate security identity name. To be
honest, I've never done a lot with cert mapping to Windows users, so this
isn't an area where I have a ton of expertise.
What you say makes common sense to me, however an experiment I did
does not support this. I exported my client certificate without the
private key and then passed the public-key-only certificate along with
my HTTPS call (System.Net.HttpWebRequest.ClientCertificates.Add). IIS
accepted the certificate and mapped it to a windows user ID. I
expected it to not accept it since the caller did not have the private
key. One guess is that the .NET framework looked up the private key
in the cert store even though I did not pass it in.

This should not have been possible. You can't do client certificate
authentication unless you have the private key available. Are you certain
that the private key was not available when you did this? If you ran this
code on the same machine, it is likely the case that the .NET client just
looked up the certificate you supplied in the file in the store on your
machine and accessed the private key that way. The file just serves as a
hint on how to look up the private key. Thus I think your guess is correct
here.
 
D

Dominick Baier

OK - i see. Maybe i misunderstood you then.

Right - first of all you need a list of approved=registered=trusted certs
- i guess i would use the hash of the public key for that.

This could be the primary key of the table - from there on you can link additional
data (stuff that cannot be found in the cert).
 
G

gudujarlson

Thanks for all the replies. What I hear you saying are the following:

- I cannot assume that anything is unique except the public key (or
public key hash), unless the CA specifically asserts it is unique.
- I can assume that IIS does authenticate that the sender of the
certificate is the owner of the private key.
- In general, I have to do my own identification of the client and
subsequent authorization.

Can you refer me to an authoritative general reference on the subject
(e.g. a book)?

One further question... does IIS need to talk to the Certificate
Authority in order to authenticate the client? If not, what exactly
am I paying for when I buy a certificate from a commercial Certificate
Authority? Why can't I make my own certificates? I'm used to making
my own private-public key pairs for SSH.
 
J

Joe Kaplan

That's basically right. I'd rephrase your second point to say that the
client "has" the private key. Ownership is more of a loaded word since it
implies that something can be stolen but still owned by someone else. :)
Essentially, the client signs some data using the private key during the
exchange with the server and the server verifies the signature using the
public key in the certificate that the client sends.

The advantage of using commercial CAs is that they typically chain up to
certificates that are built in to the Windows trusted root certificate
store, so they will be trusted as coming from a known source. Certificates
issued by roots that don't chain to a known trusted root will not verify
automatically unless both parties choose to accept the root CA as a trusted
root.

If your system is issuing the client certificates, then they can be issued
by any CA you want as long as you can convince your clients to trust the
certificate and you configure your servers to do the same. However, if you
need to accept arbitrary certificates, this becomes impractical.

The primary benefit of using certificates and PKI over raw keys is that
there is this hierarchical notion of trust that allows you to know something
about the owners of the keys without having to exchange them manually in
advance. Certificates also attempt to associate some identity info with a
key as well as a validity period and usage restrictions.

The only reason why either party would attempt to contact any of the CAs in
the chain would be to check the certificate revocation list (CRL) of any of
the CAs to see whether or not a particular certificate has been revoked.
Everything else is already in the certificate itself.

I'm not sure about a book, but perhaps Practical Cryptography would be a
good start?

Joe K.
 

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

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top