On Mon, Apr 19, 2010 at 1:49 PM, John Nagle <na...@animats.com> wrote: > exar...@twistedmatrix.com wrote: >> >> On 04:51 pm, na...@animats.com wrote: >>> >>> I'm converting some code from M2Crypto to the new "ssl" module, and >>> I've found what looks like a security hole. The "ssl" module will >>> validate the certificate chain, but it doesn't check that the certificate >>> is valid for the domain. >>> > ... >> >> It's a bit debatable. There probably should be a way to make this happen, >> but it's far from clear that it's the only correct behavior. And, as it >> turns out, there is a way to make it happen - call getpeercert() and perform >> the check yourself. ;) > > "Checking it yourself" is non-trivial. The checking code has to > understand DNS wildcards and additional domains in cert extensions. > The SSL module doesn't seem to let you read all the cert extensions, > (in particular, you don't get "certificatePolicies", so you can't > tell if a cert is an "extended validation" cert) but it looks like > you do get the subjectAltName fields present in the extensions, like this: > > subjectAltName = (('DNS', 'www.chapinfurniture.com'), > ('DNS', 'chapinfurniture.com'))) > > So it's at least possible to check. Almost. > > (DNS wildcards look like this: "*.example.com". It's also possible > to have "*.*.example.com". However, no DNS wildcard cert should cover > more than one second-level domain (huge security hole if you allow that) > and no extended validation cert should have a wildcard.) > > There may also be issues with internationalized domain names. > > It's very bad for the "ssl" module to both ignore this check and > not have that mentioned prominently in the documentation. This is > a security-critical function. Somewhere, there's a Python program that > can be exploited due to this bug. > > Here's a comparison of what M2Crypto and the SSL module return, for > "verisign.com", which uses most cert features. > > Trying domain "www.verisign.com" > Host: www.verisign.com Port: 443 > > Info from "M2Crypto: module: > > Cipher = DHE-RSA-AES256-SHA > Subject info: [('CN', 'verisign.com'), > ('OU', 'production Security Services '), > ('O', 'VeriSign, Inc.'), > ('streetAddress', '487 East Middlefield Road'), > ('L', 'Mountain View'), > ('ST', 'California'), > ('postalCode', '94043'), > ('C', 'US'), > ('serialNumber', '2497886'), > ('2.5.4.15', 'V1.0, Clause 5.(b)'), > ('jurisdictionOfIncorporationStateOrProvinceName', 'Delaware'), > ('jurisdictionOfIncorporationCountryName', 'US')] > > Certificate has 10 extensions. > Extension #0: subjectAltName = DNS:verisign.com, DNS:www.verisign.com, > DNS:verisign.mobi, DNS:www.verisign.mobi, DNS:verisign.eu, DN > S:www.verisign.eu > Extension #1: basicConstraints = CA:FALSE > Extension #2: subjectKeyIdentifier = > 0F:75:C5:F7:06:11:CE:74:FC:5F:DA:B6:2A:53:CE:39:1C:D6:7D:19 > Extension #3: keyUsage = Digital Signature, Key Encipherment > Extension #4: crlDistributionPoints = > URI:http://EVIntl-crl.verisign.com/EVIntl2006.crl > > Extension #5: certificatePolicies = Policy: 2.16.840.1.113733.1.7.23.6 > CPS: https://www.verisign.com/rpa > > Extension #6: extendedKeyUsage = TLS Web Server Authentication, TLS Web > Client Authentication, Netscape Server Gated Crypto > Extension #7: authorityKeyIdentifier = > keyid:4E:43:C8:1D:76:EF:37:53:7A:4F:F2:58:6F:94:F3:38:E2:D5:BD:DF > > Extension #8: authorityInfoAccess = OCSP - > URI:http://EVIntl-ocsp.verisign.com > CA Issuers - URI:http://EVIntl-aia.verisign.com/EVIntl2006.cer > > Extension #9: UNDEF = None > > Info from "ssl" module: > > SSL cert for "www.verisign.com": > notAfter = Apr 2 23:59:59 2012 GMT > subject = ((('1.3.6.1.4.1.311.60.2.1.3', u'US'),), > (('1.3.6.1.4.1.311.60.2.1.2', u'Delaware'),), > (('2.5.4.15', u'V1.0, Clause 5.(b)'),), > (('serialNumber', u'2497886'),), > (('countryName', u'US'),), > (('postalCode', u'94043'),), > (('stateOrProvinceName', u'California'),), > (('localityName', u'Mountain View'),), > (('streetAddress', u'487 East Middlefield Road'),), > (('organizationName', u'VeriSign, Inc.'),), > (('organizationalUnitName', u'production Security Services > '),), > (('commonName', u'verisign.com'),)) > > > John Nagle > -- > http://mail.python.org/mailman/listinfo/python-list >
I talked about this in my pycon lighting talk- it's actually been known for some time, and in fact there's some comments in Zope core that mention this problem being a motivation for rewriting SSL support from scratch. IIRC (I seem to recall this, but I seem to have lost my test harness for it) it also impacts higher level libraries like urllib, but I would verify that before taking it as gospel. Several of the other members of python-crypto would know more about it than I. As a side note, it also impacts IronPython. Geremy Condra -- http://mail.python.org/mailman/listinfo/python-list