1

I am trying to connect to a legacy (windows server 2008R2) server using python / winrm. I am seeing an issue where openssl can establish the ssl socket cleanly, but python and winrm can't. I am using python3.12 on ubuntu 24.04 (noble)

here is the python code:

import ssl, socket
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
ctx.verify_mode = ssl.CERT_NONE
with socket.create_connection(('server.example.com', 5986)) as sock:
    ssock = ctx.wrap_socket(sock)
    print(ssock.cipher(), ssock.version())

this code fails with the following error:

SSLEOFError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1010)

and here is the output from openssl s_client -connect:

CONNECTED(00000003)
depth=0 CN = server.example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = server.example.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:CN = server.example.com
   i:CN = server.example.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFADCC....
-----END CERTIFICATE-----
subject=CN = server.example.com

issuer=CN = server.example.com

---
No client certificate CA names sent
Peer signing digest: SHA1
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2084 bytes and written 505 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-SHA384
    Session-ID: E223.....
    Session-ID-ctx:
    Master-Key: 83FBC.....
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1751134634
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
    Extended master secret: yes
---

they both see the unexpected EOF, but it looks like python can't handle the unexpected EOF gracefully while openssl can. Is there anything I can do to establish the ssl connection in python like I can with openssl or curl?

4
  • 1
    the wrap_socket method has a flag called do_handshake_on_connect that defaults to true. so the wrap socket triggers the ssl handshake which is what throws the error. If you're curious, you can read about it Commented Jun 28 at 18:32
  • Mr. President, thank you for the assist on the port. I've edited the code above, but it yields the same result. Commented Jun 28 at 18:34
  • This is just a wild guess, but perhaps the peer implementation expects to see a TLS close_notify alert, which Python's ssl typically does not send. Try an experiment where the last statement in your with context manager is ssock.unwrap(), and see what happens. Commented Jun 28 at 19:14
  • @2ps: "they both see the unexpected EOF" - there is no such indication in the openssl s_client output you show. It only complains that the certificate cannot be verified, not about EOF. Commented Jun 28 at 19:47

1 Answer 1

1

The problem is likely a failure to use Server Name Indication, i.e. sending the hostname inside the TLS handshake. openssl s_client does this for many years by default, i.e. unless explicitly disabled with -noservername. SNI is required by many servers and failure to provide it can result in effects you see.

If this is the problem then the fix is like this:

ssock = ctx.wrap_socket(sock, server_hostname='server.example.com')
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.