[ python-Bugs-1583946 ] SSL "issuer" and "server" functions problems - security

SourceForge.net noreply at sourceforge.net
Wed Oct 25 00:40:21 CEST 2006


Bugs item #1583946, was opened at 2006-10-24 18:32
Message generated for change (Comment added) made by nagle
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1583946&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Library
Group: None
Status: Open
Resolution: None
Priority: 7
Private: No
Submitted By: John Nagle (nagle)
Assigned to: Nobody/Anonymous (nobody)
Summary: SSL "issuer" and "server" functions problems - security 

Initial Comment:
(Python 2.5 library)

    The Python SSL object offers two methods from
obtaining the info from an SSL certificate, "server()"
and "issuer()".  These return strings.

    The actual values in the certificate are a series
of key /value pairs in ASN.1 binary format.  But what
"server()" and "issuer()" return are single strings,
with the key/value pairs separated by "/". 

    However, "/" is a valid character in certificate
data. So parsing such strings is ambiguous, and
potentially exploitable.

    This is more than a theoretical problem.  The
issuer field of Verisign certificates has a "/" in the
middle of a text field:

"/O=VeriSign Trust Network/OU=VeriSign,
Inc./OU=VeriSign International Server CA - Class
3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY
LTD.(c)97 VeriSign".

Note the 

  "OU=Terms of use at www.verisign.com/rpa (c)00"

with a "/" in the middle of the value field.  Oops.

    Worse, this is potentially exploitable.  By
ordering a low-level certificate with a "/" in the
right place, you can create the illusion (at least for
flawed implementations like this one) that the
certificate belongs to someone else.  Just order a
certificate from GoDaddy, enter something like this in
the "Name" field

    "Myphonyname/C=US/ST=California/L=San Jose/O=eBay
Inc./OU=Site Operations/CN=signin.ebay.com"

and Python code will be spoofed into thinking you're eBay.

   Fortunately, browsers don't use Python code.

   The actual bug is in

    python/trunk/Modules/_ssl.c

at

    if ((self->server_cert =
SSL_get_peer_certificate(self->ssl))) {
       
X509_NAME_oneline(X509_get_subject_name(self->server_cert),
                  self->server, X509_NAME_MAXLEN);
       
X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
                  self->issuer, X509_NAME_MAXLEN);

The "X509_name_oneline" function takes an X509_NAME
structure, which is the certificate system's
representation of a list, and flattens it into a
printable string.  This is a debug function, not one
for use in production code.  The SSL documentation for
"X509_name_oneline" says:   

    "The functions X509_NAME_oneline() and
X509_NAME_print() are legacy functions which produce a
non standard output form, they don't handle multi
character fields and have various quirks and
inconsistencies.  Their use is strongly discouraged in
new applications."

What OpenSSL callers are supposed to do is call
X509_NAME_entry_count() to get the number of entries in
an X509_NAME structure, then get each entry with
X509_NAME_get_entry().  A few more calls will obtain
the name/value pair from the entry, as UTF8 strings,
which should be converted to Python UNICODE strings.
OpenSSL has all the proper support, but Python's shim
doesn't interface to it correctly. 

X509_NAME_oneline() doesn't handle Unicode; it converts
non-ASCII values to "\xnn" format. Again, it's for
debug output only.

So what's needed are two new functions for Python's SSL
sockets to replace "issuer" and "server".  The new
functions should return lists of Unicode strings
representing the key/value pairs. (A list is needed,
not a dictionary; two strings with the same key
are both possible and common.)

The reason this now matters is that new "high
assurance" certs, the ones that tell you how much a
site can be trusted, are now being deployed, and to use
them effectively, you need that info.  Support for them
is in Internet Explorer 7, so they're going to be
widespread soon. Python needs to catch up.

And, of course, this needs to be fixed as part of
Unicode support.  


                John Nagle
                Animats


----------------------------------------------------------------------

>Comment By: John Nagle (nagle)
Date: 2006-10-24 22:40

Message:
Logged In: YES 
user_id=5571

The problem isn't in the version of OpenSSL used in Python,
which is at 0.9.8a.  OpenSSL has had the necessary functions
for years.  But Python isn't using them.

It's in  "python/trunk/Modules/_ssl.c", as described above.  

----------------------------------------------------------------------

Comment By: Gregory P. Smith (greg)
Date: 2006-10-24 22:05

Message:
Logged In: YES 
user_id=413

Yes OpenSSL 0.9.8d or later should be used for a new binary
release.

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-4343

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3738

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-2940

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-2937


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1583946&group_id=5470


More information about the Python-bugs-list mailing list