smtplib.SMTP starttls fails with tlsv1 alert decode error

openssl, python-3.4, smtp, smtplib, ssl

Solution

According to a tcpdump the code in 3.4 sends in SNI extension with an empty target name. SNI (Server Name Indication) is used when having different certificates behind the same IP address. I consider this a bug: if it does not have a name it should not send the SNI extension instead of sending an extension with a zero-length name in it.

Problem

I encountered the following perculiar behaviour today. The following code works on Python 3.3: ``` smtp = smtplib.SMTP() smtp.connect(host="smtp.gmail.com", port=587) smtp.ehlo() smtp.starttls() ``` In Python 3.4 the above code doesn't work, instead the following error is encountered: ``` File "smtp_test.py", line 10, in <module> smtp.starttls() File "/usr/lib/python3.4/smtplib.py", line 676, in starttls server_hostname=server_hostname) File "/usr/lib/python3.4/ssl.py", line 344, in wrap_socket _context=self) File "/usr/lib/python3.4/ssl.py", line 540, in __init__ self.do_handshake() File "/usr/lib/python3.4/ssl.py", line 767, in do_handshake self._sslobj.do_handshake() ssl.SSLError: [SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:598) ``` If the above code is modified to specify the host and port in the constructor and not use the connect method, as in the code below, then it works. ``` smtp = smtplib.SMTP(host="smtp.gmail.com", port=587) smtp.ehlo() smtp.starttls() ``` The above behaviour occurs with OpenSSL version 1.0.1f and OpenSSL 1.0.1g Could someone explain this behaviour to me ?

Original source