I have a very old Windows 2003 server and I need to test TLSv1 connections to it.
I found some simple HTTPS server example code for GoLang to configure it to use TLSv1. I also created a simple Python3 HTTPS client with the requests module that I am running on my Windows 11 machine.
When I try to connect to the GoLang server on the Windows 2003 server with TLSv1 using the Python3 application, I get 'tls internal error' (see screenshot below).
How can I get the TLSv1 connection to work?
Error:
GoLang server code:
package main
import (
"crypto/tls"
"fmt"
"log"
"net/http"
"runtime"
)
func main() {
fmt.Printf("Hello %s/%s\n", runtime.GOOS, runtime.GOARCH)
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
w.Write([]byte("This is an example server.\n"))
})
cfg := &tls.Config{
MinVersion: tls.VersionTLS10,
MaxVersion: tls.VersionTLS10,
}
srv := &http.Server{
Addr: ":443",
Handler: mux,
TLSConfig: cfg,
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
}
log.Fatal(srv.ListenAndServeTLS("server.crt", "server.key"))
}
Python3 client code:
from requests_toolbelt import SSLAdapter
import requests
import ssl
s = requests.Session()
p = ssl.PROTOCOL_TLSv1
s.mount('https://', SSLAdapter(p))
r = s.get('https://10.2.2.14/', verify=False)
Python3 Client output:
Traceback (most recent call last):
File "C:<>Programs\Python\Python311\Lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\urllib3\connectionpool.py", line 386, in _make_request
self._validate_conn(conn)
File "C:<>Programs\Python\Python311\Lib\site-packages\urllib3\connectionpool.py", line 1042, in _validate_conn
conn.connect()
File "C:<>Programs\Python\Python311\Lib\site-packages\urllib3\connection.py", line 414, in connect
self.sock = ssl_wrap_socket(
^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\urllib3\util\ssl_.py", line 453, in ssl_wrap_socket
ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\urllib3\util\ssl_.py", line 495, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\ssl.py", line 517, in wrap_socket
return self.sslsocket_class._create(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\ssl.py", line 1075, in _create
self.do_handshake()
File "C:<>Programs\Python\Python311\Lib\ssl.py", line 1346, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL] internal error (_ssl.c:1002)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:<>Programs\Python\Python311\Lib\site-packages\requests\adapters.py", line 489, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\urllib3\util\retry.py", line 592, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='10.2.2.14', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL] internal error (_ssl.c:1002)')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:tls_1.0_test_server\test-tls-connect.py", line 24, in <module>
r = s.get('https://10.2.2.14/', verify=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\requests\sessions.py", line 600, in get
return self.request("GET", url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\requests\sessions.py", line 587, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\requests\sessions.py", line 701, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:<>Programs\Python\Python311\Lib\site-packages\requests\adapters.py", line 563, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='10.2.2.14', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL] internal error (_ssl.c:1002)')))
Recent systems have TLS 1.0 disabled by default. One need to explicitly allow this by setting the SECLEVEL in the cipher string. Simply using SSLAdapter with the protocol version is not sufficient for this.
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import requests
import ssl
class MyAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
# set low Security Level to allow TLSv1
context.set_ciphers('DEFAULT:@SECLEVEL=0')
super().init_poolmanager(*args, **kwargs, ssl_context=context)
s = requests.Session()
s.mount('https://', MyAdapter())
r = s.get('https://10.2.2.14/', verify=False)