You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ssl.SSLObject method getpeercert() is buggy, do_handshake() is strange #73520
In my experiments with the relatively new class SSLObject from the ssl module I've noticed the following behavior(s) which I think can be described as bugs.
The getpeercert() method raises a ValueError exception "handshake not done" even after the handshake has successfully completed. If, however, I call the do_handshake() method *after* the handshake completes, then getpeercert() correctly runs and returns the peer's certificate. So now let's focus on do_handshake(). This method is basically undocumented, which I thought was ok because what it does should be obvious. It does seem to initiate a handshake if it's the first method call after the SSLObject is created. If called afterward, it doesn't outwardly appear to do anything, but as mentioned previously it does magically make the getpeercert() method start working.
Oddly, I expected to run into this with my code using SSLObject in trio [1], but if I connect to python.org:443 and then 'await trio_ssl_stream.do_handshake(); trio_ssl_stream.getpeercert()' it works just fine ... even though when I run the sslbugs.py script I get the same weird results Greg reports. As far as I can tell the logic is identical. So I guess this might potentially be useful to narrow this down :-).
Activity
GregStark commentedon Jan 20, 2017
In my experiments with the relatively new class SSLObject from the ssl module I've noticed the following behavior(s) which I think can be described as bugs.
The getpeercert() method raises a ValueError exception "handshake not done" even after the handshake has successfully completed. If, however, I call the do_handshake() method *after* the handshake completes, then getpeercert() correctly runs and returns the peer's certificate. So now let's focus on do_handshake(). This method is basically undocumented, which I thought was ok because what it does should be obvious. It does seem to initiate a handshake if it's the first method call after the SSLObject is created. If called afterward, it doesn't outwardly appear to do anything, but as mentioned previously it does magically make the getpeercert() method start working.
tiran commentedon Jan 20, 2017
Hi Grek,
can you provide a script to reproduce the problem, please?
GregStark commentedon Jan 20, 2017
Christian,
I will gladly do so a little later today. Thanks for your quick response.
--greg
On Fri, Jan 20, 2017 at 7:29 AM, Christian Heimes <report@bugs.python.org>
wrote:
GregStark commentedon Jan 20, 2017
adding script the illustrates the bug.
njsmith commentedon May 23, 2017
Oddly, I expected to run into this with my code using SSLObject in trio [1], but if I connect to python.org:443 and then 'await trio_ssl_stream.do_handshake(); trio_ssl_stream.getpeercert()' it works just fine ... even though when I run the sslbugs.py script I get the same weird results Greg reports. As far as I can tell the logic is identical. So I guess this might potentially be useful to narrow this down :-).
Test code that works:
@trio.run
async def main():
import trio
sock = trio.socket.socket()
addr = await sock.resolve_remote_address(("python.org", 443))
await sock.connect(addr)
s = trio.SocketStream(sock)
client = trio.ssl.SSLStream(
s, trio.ssl.create_default_context(), server_hostname="python.org")
await client.do_handshake()
print(client.getpeercert())
[1] Currently in python-trio/trio#107, eventually will be at https://github.com/python-trio/trio/blob/master/trio/ssl.py
tiran commentedon May 23, 2017
The issue with getpeercert() is a side-effect of your issue bpo-30141. The peer certificate is cached in do_handshake.
tiran commentedon May 23, 2017
New changeset 66dc33b by Christian Heimes in branch 'master':
bpo-29334: Fix ssl.getpeercert for auto-handshake (bpo-1769)
66dc33b
tiran commentedon Jun 12, 2017
Also needs backport to 2.7 for bpo-22559
ned-deily commentedon Jul 1, 2017
Is anything holding this up for merging into 3.6 and/or 3.5?
tiran commentedon Sep 5, 2017
New changeset 63b3f2b by Christian Heimes in branch '3.6':
[3.6] bpo-29334: Fix ssl.getpeercert for auto-handshake (GH-1769) (bpo-1778)
63b3f2b
tiran commentedon Feb 26, 2018
The fix hasn't been ported to 2.7 yet.
tiran commentedon Feb 26, 2018
The fix hasn't been ported to 2.7 yet.
iritkatriel commentedon Sep 19, 2020
Backport to 2.7 is no longer relevant, so I think this issue can be closed.