Michael Ströder wrote: > John Nagle wrote: > >> The Python SSL object offers two methods from obtaining >>the info from an SSL certificate, "server()" and "issuer()". >>The actual values in the certificate are a series of name/value >>pairs in ASN.1 binary format. But what "server()" and "issuer()" >>return are strings, with the pairs separated by "/". The >>documentation at "http://docs.python.org/lib/ssl-objects.html" >>says "Returns a string containing the ASN.1 distinguished name >>identifying the server's certificate. (See below for an example showing >>what distinguished names look like.)" There is, however, no "below". >> >>What you actually get back looks like this, which is Google's certificate: >> >>"/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com" >> >>So, no problem; just split on "/", right? >> >>Unfortunately, "/" is a legal character in certificate values. > > > You hit a really serious problem: There's no completely well-defined > string representation format for distinguished names used in X.509 > certificates. The format above is what OpenSSL used in the beginning. > Yuck! IMO this is also a security problem in some cases. > > The best thing would be to stick to RFC 4514 (formerly RFC 2253: > Lightweight Directory Access Protocol (LDAP): String Representation of > Distinguished Names). It defines a UTF-8-based string representation. ... > Guess the second is what Python SSL object also should return. No idea > whether this is available at OpenSSL's API level. > That's exactly what I suggested in my Python bug report update.
OpenSSL has all the right functions. Almost. OpenSSL has "X509_NAME_oneline()" which is deprecated, which Python is using, and which uses "/" as a delimiter without escaping "/" in content. OpenSSL also has "X509_NAME_print_ex", which does the right thing - outputs a UTF8 string in RFC 2253 format, with all the right escapes and Unicode compatibility if you ask for Unicode output. Unfortunately, "X509_NAME_print_ex" is set up to output to an I/O port, not a string. There's no comparable function in OpenSSL to edit that info to a string. All the right machinery to do the job is in openssl/crypto/asn1/a_strex.c but they ran into a classic C problem. They have code designed to output to a stream of infinite length, and don't have a way to get the target length down to the copy function. Take look at "send_mem_chars" in that file, which is turned off. If it were used, it would have buffer overflow potential. This could be fixed, but it's a pain. It's local to that file, though; someone who owns that code could fix it in an hour. X509_NAME_oneline(), the deprecated function, is in a completely separate file and doesn't handle the hard cases at all. The same problem was reported in Apache mod_ssl back in 2004. See http://mail-archives.apache.org/mod_mbox/httpd-dev/200410.mbox/[EMAIL PROTECTED] And it had to be fixed in OpenCA. See http://www.mail-archive.com/openca-devel@lists.sourceforge.net/msg02672.html Also, there may be an exploitable bug in MySQL that depends on this. See http://bugs.mysql.com/bug.php?id=17208 Get the OpenSSL people to fix their API, and the Python fix will be a one-line change. John Nagle -- http://mail.python.org/mailman/listinfo/python-list