WebApp Sec mailing list archives

RE: How to perform SSL certificate validation ?


From: "Wall, Kevin" <Kevin.Wall () qwest com>
Date: Mon, 10 Jul 2006 19:11:19 -0500

Nagareshwar Talekar wrote...

      1) Check if certificate is not expired.
      2) Common name on the certificate matches the DNS name 
of the server.
      3) Checks if the CA is trused.

 I don't know how to perform the check for 3rd step. How can we ensure
 that CA is trusted? One of my colleague told that I have to 
store all trusted
 root certificates and then compare incoming certificate with 
existing ones..

Depending on your implementation language, this isn't that hard.

If you are using JSSE (and probably .NET, I imagine), then about all you
need to do is to place the CA's certificate in your "trusted key store"
and the test is down automagically to see if the server certificate has
been signed by a trusted CA.

In Java, by default, the trusted key store is the file
$JAVA_HOME/jre/lib/security/cacerts, although this can be changed
via the System property "javax.net.ssl.trustStore". Your mileage
will vary for other programming languages.

 Also I was told that certificate validation is done to prevent the
SSL-MITM attack
 Is this the only reason or is there any other reason for which the
SSL certificate validation is done ?

IMO, I'd say that preventing a MITM attack is a _secondary_ reason. I
think
the primary reason is for the client to do SERVER authentication. I.e.,
to
make sure that it is communicating with the server that it desires to be
communicating with. (E.g., prevent simple DNS spoofing attacks, etc.)

Generally, you are missing the 4th step that most do, which is to check
to see if the server certificate (or the CA's signing cert) has expired.

Then if you want to be a bit more paranoid, you should also check to see
if
the server certificate (and technically, the CA's signing cert) was
revoked.

And a bunch of other stuff. Details vary depending on your threat model
and
programming language (which I don't think you mentioned).

 It will be great if you can throw some light in this matter.

Light? Maybe. (But I can drown you with a fire hose! ;-)

FWIW, I'll share what I have with others on this subject. And I'm by no
means an expert on this (at least as compared to those like Eric
Rescorla,
etc.) I wrote this up because I never found anything similar to this on
the web anywhere...at least nothing that required more than reading 25
pages
or some complicated technical document.

NOTE: Std Disclaimer applies. These are my opinions / thoughts and not
necessarily those of my company; any mistakes are mostly likely my own;
etc.


                === +++ === Begin Long-winded Explanation === +++ ===

In addition, the client really SHOULD do the following:

[[[
                                        Aside - some definitions
Critical extensions: Attributes on certificates that are required.
    If ignored, some security risk is implied to parties using the
    certificate.

Non-critical extensions: Optional, but if used, then they should be
    correct, *IF* understood! Otherwise, cert should be rejected as
    invalid.  If non-critical extension is "not understood", it is
    not interpreted, so it cannot be wrong. Thus it is optional not
    only to provide non-critical extensions, but also optional as to
    whether they are interpreted by a system validating certificates.

In theory (according to the X.509v3 standard) criticality is indicated
by cert issuer, but in practice, there usually is somewhat common
agreement (based on various revised PKCS standards) as to what
attributes
are and are not critical. Unfortunately, many CAs (e.g., Verisign)
continue to ignore this common practice.

]]]

        1) Check if the name on the server's certificate (SubjectDN
           attribute or the Alternatename attribute) matches the name
           of the server it is connecting to. For this to work
           (automagically, via JSSE for example) the SubjectDN on
           the certificate should take the form of:

                cn=fqhn, ou=...whatever...

           where 'fqhn' is the "fully qualified host name" of the server
           (or a wild-card cert) and the '...whatever...' is usually
something
           that identifies the department and/or group. E.g.,
  CN=myserver.qwest.com,OU=Application Security,O=Qwest
IT,L=Dublin,S=Ohio,C=US

        2) Check if the current date/time is between the 'Valid from'
and
       'Valid to' dates.

        3) Check with the CA (via a CRL Distribution list or an OSCP
server)
       whether the server's cert has been revoked. (Both which should
       really use SSL/TLS, but that might be a chicken-&-egg problem
       if that SSL/TLS connection did this test. :-)

        4) Validate any Critical Extensions (including checking
       Basic Constraints, which _should_ always be marked as
       a critical extension, (but often isn't; note this is one
           that the Microsoft CA got correct--probably because they were
       bitten by it--but may other CAs, such as Verisign, don't!)

        5) Validate that the key usage extension (if present) is for
       "server authentication" (or in case of a root/intermediate
       CA cert) valid for "certificate signing").  

        6) If Basic Constraints is specified (it really always should
be),
       then check if there are any 'path length constraints' on the CA
       cert chain and make sure that the CA cert chain (starting at
       current cert) is <= this constraint.

        7) If Basic Constraints are specified and "name constraints" are
       specified, check to make sure that the FQHN on the CN of the
       SubjectDN belongs to one of the domains specified in the name
       constraints.

        8) Repeat each of the above steps for each CA in the CA's
       certification path all the way up to the top-most CA.
       (Applies only if the server is signed by a CA chain.)

In practice, only web browsers usually do this most of this checking.
(I am not sure that any of them do them ALL.) Yet failure to do so
could leave you vulnerable to certain exploits. It would be nice if
JSSE and other popular class libraries implementing SSL/TLS did
these by default, but JSSE at least only handles #1 and #2 AFAIK.

One example of this that happened maybe 3 or 4 years ago was Verisign
issued their class 3 certs with "basic constraints" not marked as a
critical extension and with no name or path constraints. This in
combination with Internet Explorer not checking these things, allowed
attackers to set up phony sites with ".microsoft.com" domain name and
signed (via a intermediate CA chain) by Verisign. They mirrored a
Microsoft-owned site and combined with some DNS cache poisoning or
outright DNS query hijacking allowed them to lure people to the
phony site. Supposedly no actual passwords were reported as stolen
but no one knows for sure. Anyway, after that MS IE and the Microsoft
CA software saw the light and fixed things. But Verisign still has
their certificates that they issued screwed up.  Caveat Emptor.

Also, the server requests the client's digital 
certificate and checks its issuer against the server's list 
of trusted CAs. If the CA of the client certificate is not in 
the server's list, the server halts further communications 
with that client.

Again, this is really the minimum needed. Once should do all the
steps outlined above. Not only that though, in addition, one needs to
make sure that the user whose identity is on this certificate is a
legitimate user for your application. That either means checking the
entire cert or minimally the SubjectDN and (probably the serial # --
at least in our case, that would be important) to see if it
corresponds to a legitimate user id.

I get asked this often enough that I probably should add it to our
company's SSL FAQ. But developers everywhere would be nodding off at
their
desks, so I haven't done it.

                =====================================================

BTW, if any of you are still awake, maybe you need to cut down on the
caffeine. ;-)           

-kevin
---
Kevin W. Wall           Qwest Information Technology, Inc.
Kevin.Wall () qwest com Phone: 614.215.4788
"The reason you have people breaking into your software all 
over the place is because your software sucks..."
 -- Former whitehouse cybersecurity advisor, Richard Clarke,
    at eWeek Security Summit


This communication is the property of Qwest and may contain confidential or
privileged information. Unauthorized use of this communication is strictly 
prohibited and may be unlawful.  If you have received this communication 
in error, please immediately notify the sender by reply e-mail and destroy 
all copies of the communication and any attachments.

-------------------------------------------------------------------------
Sponsored by: Watchfire

Cross-Site Scripting (XSS) is one of the most common application-level
attacks that hackers use to sneak into web applications today. This
whitepaper will discuss how traditional CSS attacks are performed, how to
secure your site against these attacks and check if your site is protected.
Cross-Site Scripting Explained - Download this whitepaper today!

https://www.watchfire.com/securearea/whitepapers.aspx?id=701500000008Vmr
--------------------------------------------------------------------------


Current thread: