I am trying to make a zeep.Client(wsdl_url, transport) to get the wsdl of a webservice. I`ve virtually seen every question on SO and also checked google for a lot of content. None of them seems to help. It seems to be a recent problem with those libraries. I am using:
wsdl_url=https://unsafewebsite.com
pyOpenSSL==23.2.0
requests==2.31.0
urllib3==2.0.6
zeep==4.2.1
First, I used nmap to get the wsdl_url
ciphers using: nmap --script ssl-enum-ciphers -p 443 wsdl_url
. It returned:
PORT STATE SERVICE
443/tcp open https
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| compressors:
| NULL
| cipher preference: server
| warnings:
| 64-bit block cipher 3DES vulnerable to SWEET32 attack
| Key exchange (dh 1024) of lower strength than certificate key
| TLSv1.1:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| compressors:
| NULL
| cipher preference: server
| warnings:
| 64-bit block cipher 3DES vulnerable to SWEET32 attack
| Key exchange (dh 1024) of lower strength than certificate key
| TLSv1.2:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 1024) - A
| TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| compressors:
| NULL
| cipher preference: server
| warnings:
| 64-bit block cipher 3DES vulnerable to SWEET32 attack
| Key exchange (dh 1024) of lower strength than certificate key
|_ least strength: D
Nmap done: 1 IP address (1 host up) scanned in 5.58 seconds
First, I tried to make a CustomCipherAdapter(HTTPAdapter), like so:
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
CIPHERS = (
"DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:"
"DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:"
"DHE-RSA-AES256-SHA256:DHE-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:"
"AES256-GCM-SHA384:AES128-SHA:AES128-SHA256:AES256-SHA:AES256-SHA256:"
"DES-CBC3-SHA"
"ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:"
"DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:"
"!eNULL:!MD5"
)
class CustomCipherAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs["ssl_context"] = context
return super(CustomCipherAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs["ssl_context"] = context
return super(CustomCipherAdapter, self).proxy_manager_for(*args, **kwargs)
And then I initialize my session object and use cert.pem and key.pem to set my client certificate to use with session, also, i set session.verify = False
, like so:
session = Session()
session.verify = False
session.cert = (cert.pem, key.pem)
After that, I would simply need to create a zeep.transport Transport and a Client, so that I could consume the wsdl_url, just like this:
# Create a SOAP client with the session
transport = Transport(session=session)
client = Client(wsdl_url, transport=transport)
I had no success. This will yield the following error:
Traceback (most recent call last):
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 467, in _make_request
self._validate_conn(conn)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 1092, in _validate_conn
conn.connect()
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connection.py", line 642, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connection.py", line 783, in _ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\util\ssl_.py", line 469, in ssl_wrap_socket
ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\util\ssl_.py", line 513, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File "C:\Users\usr\AppData\Local\Programs\Python\Python310\lib\ssl.py", line 513, in wrap_socket
return self.sslsocket_class._create(
File "C:\Users\usr\AppData\Local\Programs\Python\Python310\lib\ssl.py", line 1071, in _create
self.do_handshake()
File "C:\Users\usr\AppData\Local\Programs\Python\Python310\lib\ssl.py", line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 790, in urlopen
response = self._make_request(
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 491, in _make_request
raise new_e
urllib3.exceptions.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\adapters.py", line 486, in send
resp = conn.urlopen(
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 844, in urlopen
retries = retries.increment(
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\util\retry.py", line 515, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='unsafewebsite.com', port=443): Max retries exceeded with url: endpointOfUnsafeWebsite (Caused by SSLError(SSLError(1, '[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997)')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\.iagre\iagre\go.py", line 237, in <module>
client = Client(wsdl_url, transport=transport, plugins=[MyLoggingPlugin()])
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\client.py", line 76, in __init__
self.wsdl = Document(wsdl, self.transport, settings=self.settings)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\wsdl\wsdl.py", line 92, in __init__
self.load(location)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\wsdl\wsdl.py", line 95, in load
document = self._get_xml_document(location)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\wsdl\wsdl.py", line 155, in _get_xml_document
return load_external(
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\loader.py", line 89, in load_external
content = transport.load(url)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\transports.py", line 123, in load
content = self._load_remote_data(url)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\transports.py", line 135, in _load_remote_data
response = self.session.get(url, timeout=self.load_timeout)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\sessions.py", line 602, in get
return self.request("GET", url, **kwargs)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\adapters.py", line 517, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='unsafewebsite.com', port=443): Max retries exceeded with url: endpointOfUnsafeWebsite (Caused by SSLError(SSLError(1, '[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997)')))
Have anyone experienced such error using zeep, and how can i correct it? Also is important to note that i cant even do requests.get(wsdl_url, cert=(cert,key)). It will yield the same error. So I guess it is a problem related to urllib3, ssl, and requests library, not zeep...