From: exarkun on 19 Apr 2010 12:50 On 04:51 pm, nagle(a)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. > > Here's the basic code: > > sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) > sock = ssl.wrap_socket(sk, ca_certs=certfile, > cert_reqs=ssl.CERT_REQUIRED) > sock.connect((domain,443)) > cert = sock.getpeercert() > print('SSL cert for "%s":' % (domain,)) > for fieldname in cert : > print(' %s = %s' % (fieldname, cert[fieldname])) > >Note that I'm sending a CA cert list and am specifying CERT_REQUIRED, >so I should get a proper cert check. > >Now let's try a host that presents the wrong SSL cert. Try, in >a browser, > > https://www.countrysidecabinetry.com > >You'll get an error. But the "ssl" module is happy with this cert: > >SSL cert for "www.countrysidecabinetry.com": > notAfter = Dec 8 23:30:48 2010 GMT > subject = ((('serialNumber', >u'E5gMXaDjnqfFPID2KNdLTVNEE6PjtqOr'),), (('countryName', u'US'),), >(('organizationName', u'customla >serengravings.com'),), (('organizationalUnitName', u'GT57631608'),), >(('organizationalUnitName', u'See www.rapidssl.com/resources/cp >s (c)09'),), (('organizationalUnitName', u'Domain Control Validated - >RapidSSL(R)'),), (('commonName', u'customlaserengravings.com') >,)) > >Note that the cert is for "customlaserengravings.com", but is being >presented by "countrysidecabinetry.com". Fail. > >When I try this with M2Crypto, I get an SSL.Checker.WrongHost >exception. >That's what should happen. 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. ;) Here's some related discussion for an equivalent API in a different module: http://twistedmatrix.com/trac/ticket/4023 At the very least, the documentation for this should be very clear about what is and is not being checked. Jean-Paul
From: exarkun on 19 Apr 2010 16:37 On 05:49 pm, nagle(a)animats.com wrote: >exarkun(a)twistedmatrix.com wrote: >>On 04:51 pm, nagle(a)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. Yes. It'd be nice to having something in the stdlib which accepted a hostname and a certificate and told you if they line up or not. >The SSL module doesn't seem to let you read all the cert extensions, Yes. That sucks. It was argued about on python-dev and ultimately the people writing the code didn't want to expose everything. I don't remember the exact argument for that position. > It's very bad for the "ssl" module to both ignore this check and >not have that mentioned prominently in the documentation. I agree. As I said, I think the behavior should be well documented. Jean-Paul
|
Pages: 1 Prev: Code redundancy Next: scipy error undefined symbol: lsame_ |