TypeError: wrap_socket() got an unexpected keyword argument 'keyfile'

There is no keyfile argument when calling context.wrap_socket(...). There is a keyfile argument when calling ssl.wrap_socket(...). The reason for this is that the context should be created with a keyfile if needed while ssl.wrap_socket(...) creates a new context.

For more details see documentation of context.wrap_socket vs. documentation of ssl.wrap_socket.

Answer from Steffen Ullrich on Stack Overflow
🌐
GitHub
github.com › Azure › azure-sdk-for-python › issues › 25434
[EventHubs] pyamqp, update deprecated ssl.wrap_socket method · Issue #25434 · Azure/azure-sdk-for-python
July 27, 2022 - created a PR for this that needs to be closed or fixed: #25433 which is failing b/c of the following error: sock = ssl.SSLContext.wrap_socket(**opts) E TypeError: wrap_socket() got an unexpected keyword argument 'keyfile'. Error in: azur...
Author   swathipil
🌐
Google Groups
groups.google.com › g › python-tornado › c › 3xuY7AfkNWY
self-signed ssl: wrap_socket: __init__() got an unexpected keyword argument 'server_hostname'
There is only one version of 2.7.8, and it was released in August. SSLContext was added in 2.7.9, which was released in December. Tornado is fully compatible with 2.7.9; the problem is that you seem to have some non-standard in-between version.
🌐
GitHub
github.com › eventlet › eventlet › issues › 526
python 3.7 - wrap_socket() got an unexpected keyword argument '_context' · Issue #526 · eventlet/eventlet
September 29, 2018 - message handler error Traceback (most recent call last): File "/home/nexodaru/Workspace/Geocatch_2.0/code/socket.io/venv/lib/python3.7/site-packages/engineio/server.py", line 411, in _trigger_event return self.handlers[event](*args) File "/home/nexodaru/Workspace/Geocatch_2.0/code/socket.io/venv/lib/python3.7/site-packages/socketio/server.py", line 518, in _handle_eio_message self._handle_connect(sid, pkt.namespace) File "/home/nexodaru/Workspace/Geocatch_2.0/code/socket.io/venv/lib/python3.7/site-packages/socketio/server.py", line 421, in _handle_connect self.environ[sid]) is False: File "/ho
Author   Nexodaru
🌐
Narkive
python-tornado.narkive.com › o3d85uSu › tornado-self-signed-ssl-wrap-socket-init-got-an-unexpected-keyword-argument-server-hostname
[tornado] self-signed ssl: wrap_socket: __init__() got an unexpected keyword argument 'server_hostname'
My python version is 2.7.8 (october build), my tornado version is 4.1.0. Here is my code for webserver, the handler implements a simple get request. def main(): options.parse_command_line() settings = { 'cookie_secret': '****', 'upload_path': UPLOAD_PATH, 'cookie_morsels': { 'httponly': True, 'max-age': 24 * 3600 # 1 day }, } ssl_options = {} ssl_options['certfile'] = '/etc/ssl/my_cert.crt' ssl_options['keyfile'] = '/etc/ssl/my_cert.key' app = web.Application([ (r"/get", handlers.GetHandler)], **settings) http_server = httpserver.HTTPServer(app, ssl_options=ssl_options, max_buffer_size=4 * 102
🌐
Python
bugs.python.org › issue9711
Issue 9711: ssl.SSLSocket's keyfile argument seems to be ignored if specified without certfile - Python tracker
August 29, 2010 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/53920
Find elsewhere
🌐
Ubuntu
bugs.launchpad.net › bugs › 1834565
Bug #1834565 “python 3.7: wrap_socket() got an unexpected keywor...” : Bugs : eventlet
June 28, 2019 - [Impact] Unable to enable TLS termination of any endpoints for OpenStack with Python 3.7. [Test Case] sudo apt install python3-eventlet python3 ", line 8, in File "/usr/lib/python3/dist-packages/eventlet/green/ssl.py", line 403, in wrap_socket return GreenS...
🌐
GitHub
github.com › urllib3 › urllib3 › issues › 3504
Got unexpected keyword argument 'key_proxy_ssl_context' error when use proxy_ssl_context on ProxyManager · Issue #3504 · urllib3/urllib3
October 29, 2024 - import ssl from urllib3 import ProxyManager proxy_ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) proxy_ssl_ctx.check_hostname = False proxy_ssl_ctx.load_cert_chain(certfile=self.cert_file, keyfile=self.key_file) proxy = ProxyManager( "https://myproxy-mtls-auth.example.com", proxy_ssl_context=proxy_ssl_ctx, cert_reqs="CERT_NONE", timeout=5, ) proxy.request("GET", "https://httpbin.org/json") # this line will throw TypeError: PoolKey.__new__() got an unexpected keyword argument 'key_proxy_ssl_context'
Author   ns-wchung
Top answer
1 of 2
23

Basically the server need to share with the client his certificate and vice versa (look the ca_certs parameter). The main problem with your code is that the handshake were never executed. Also, the Common Name string position depends on how many field did specified in the certificate. I had been lazy, so my subject has only 4 fiels, and Common Name is the last of them.

Now it works (feel free to ask for further details).

Server

#!/bin/usr/env python
import socket
import ssl
import pprint

#server
if __name__ == '__main__':

    HOST = '127.0.0.1'
    PORT = 1234

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind((HOST, PORT))
    server_socket.listen(10)

    client, fromaddr = server_socket.accept()
    secure_sock = ssl.wrap_socket(client, server_side=True, ca_certs = "client.pem", certfile="server.pem", keyfile="server.key", cert_reqs=ssl.CERT_REQUIRED,
                           ssl_version=ssl.PROTOCOL_TLSv1_2)

    print repr(secure_sock.getpeername())
    print secure_sock.cipher()
    print pprint.pformat(secure_sock.getpeercert())
    cert = secure_sock.getpeercert()
    print cert

    # verify client
    if not cert or ('commonName', 'test') not in cert['subject'][3]: raise Exception("ERROR")

    try:
        data = secure_sock.read(1024)
        secure_sock.write(data)
    finally:
        secure_sock.close()
        server_socket.close()

Client

import socket
import ssl

# client
if __name__ == '__main__':

    HOST = '127.0.0.1'
    PORT = 1234

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setblocking(1);
    sock.connect((HOST, PORT))

    context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
    context.verify_mode = ssl.CERT_REQUIRED
    context.load_verify_locations('server.pem')
    context.load_cert_chain(certfile="client.pem", keyfile="client.key")

    if ssl.HAS_SNI:
        secure_sock = context.wrap_socket(sock, server_side=False, server_hostname=HOST)
    else:
        secure_sock = context.wrap_socket(sock, server_side=False)

    cert = secure_sock.getpeercert()
    print cert

    # verify server
    if not cert or ('commonName', 'test') not in cert['subject'][3]: raise Exception("ERROR")

    secure_sock.write('hello')
    print secure_sock.read(1024)

    secure_sock.close()
    sock.close()

Take a look:

Ps: I made the client print the server response.

Response to comments

On client's side you never used the context variable I've created. Does it mean it's unnecessary here?

Documentation says:

For more sophisticated applications, the ssl.SSLContext class helps manage settings and certificates, which can then be inherited by SSL sockets created through the SSLContext.wrap_socket() method.

I've updated the code to show you the differences: the server uses ssl.wrap_socket(), the client ssl.SSLContext.wrap_socket().

Second, what's the point in checking if ssl.HAS_SNI when the socket creation looks the same in if and else? With your approach I cant use server_hostname=HOST in socket wrapping method.

You are right, in the updated code I used server_hostname=HOST.

Another thing: you're using ca_certs instead of using load_verify_locations in context I created. Why? Are those 2 methods identical?

My fault, I was using ca_cert as parameter of ssl.wrap_socket(), so I didn't used the context at all. Now I use it.

And another thing: do you really need to call secure_sock.do_handshake() by yourself?

Nope, I forgot to remove it :)

The output is exactly the same.

2 of 2
4

ilario-pierbattista Answer but in python 3:

  • Check print function
  • Check secure_sock.write(b'hello') in bytes
  • Check function argument (config)
def start_client_side(config):
    HOST = config['host']
    PORT = config['port']
    pemServer = config['serverpem']
    keyClient = config['clientkey']
    pemClient = config['clientpem']

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setblocking(1);
    sock.connect((HOST, PORT))

    context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
    context.verify_mode = ssl.CERT_REQUIRED
    context.load_verify_locations(pemServer)
    context.load_cert_chain(certfile=pemClient, keyfile=keyClient)

    if ssl.HAS_SNI:
        secure_sock = context.wrap_socket(sock, server_side=False, server_hostname=HOST)
    else:
        secure_sock = context.wrap_socket(sock, server_side=False)

    cert = secure_sock.getpeercert()
    print(pprint.pformat(cert))

    # verify server
    if not cert or ('commonName', 'server.utester.local') not in itertools.chain(*cert['subject']): raise Exception("ERROR")

    secure_sock.write(b'hello')
    print(secure_sock.read(1024))

    secure_sock.close()
    sock.close()

def start_server_side(config):
    HOST = config['host']
    PORT = config['port']
    pemServer = config['serverpem']
    keyServer = config['serverkey']
    pemClient = config['clientpem']

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind((HOST, PORT))
    server_socket.listen(10)

    client, fromaddr = server_socket.accept()
    secure_sock = ssl.wrap_socket(client, server_side=True, ca_certs=pemClient, certfile=pemServer,
                                  keyfile=keyServer, cert_reqs=ssl.CERT_REQUIRED,
                                  ssl_version=ssl.PROTOCOL_TLSv1_2)

    print(repr(secure_sock.getpeername()))
    print(secure_sock.cipher())
    cert = secure_sock.getpeercert()
    print(pprint.pformat(cert))

    # verify client
    if not cert or ('commonName', 'client.utester.local') not in itertools.chain(*cert['subject']): raise Exception("ERROR")

    try:
        data = secure_sock.read(1024)
        secure_sock.write(data)
    finally:
        secure_sock.close()
        server_socket.close()
Top answer
1 of 2
2

The patch you're mentioning is for Python 3.2, and you're using Python 2.7. Issue 5639 also seems to indicate there is no plan to back-port SNI support for Python 2.7.

You could wrap the socket with pyOpenSSL instead (its Connection class has a set_tlsext_host_name since version 0.13. (I'm not sure which version comes with Debian 7.3, you might want to set up a virtualenv and upgrade to a newer version locally, if needed.)

There is an SNI example is the pyOpenSSL repository.

If you want your usage of wrap_socket to be more compatible with the trick were you replace the value of sock in an httplib connection, you could have a look at how urllib3 does this with pyOpenSSL. Essentially, it creates an OpenSSL.SSL.Connection from an existing socket, but since that connection isn't compatible with a socket, it wraps it into a class that implements the required method.

(By the way, in Python 2.7, urllib, urllib2 and httpconnection don't do any certificate verification at all, unless you implement it yourself by wrapping their sockets.)

EDIT:

Here is a version of your code that should work with Python 3.2. Unfortunately, the server_name parameter isn't in the plain ssl.wrap_socket, only in SSLContext.wrap_socket, but you can use SSLSocket directly.

import socket
import ssl

CA_BUNDLE_FILE="/etc/ssl/certs/ca-certificates.crt"


HOST = "sni.velox.ch"
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = ssl.SSLSocket(sock=s1, ca_certs=CA_BUNDLE_FILE,
                     cert_reqs=ssl.CERT_REQUIRED,
                     ssl_version=ssl.PROTOCOL_TLSv1,
                     server_hostname=HOST)

s2.connect((HOST, 443))

s2.send(bytes("GET / HTTP/1.1\n", "UTF-8"))
# This might need to be modified when using another port
s2.send(bytes("Host: %s\n" % (HOST,), "UTF-8"))
s2.send(bytes("\n", "UTF-8"))

# Certainly not the best way to read the response, but it works.
while True:
    x = s2.read()
    if not x:
        break
    print(x)
2 of 2
0

My env is:requests==2.7.0, python-2.7.5-34.el7.x86_64, gevent==1.0.2

Change python version to python-2.7.5-18.el7_1.1.x86_64, problem is solved.

on CentOS:

sudo rpm -Uvh --oldpackage python-devel-2.7.5-18.el7_1.1.x86_64.rpm  python-libs-2.7.5-18.el7_1.1.x86_64.rpm  python-2.7.5-18.el7_1.1.x86_64.rpm

pakages can search on google.

🌐
GitHub
github.com › boto › boto3 › issues › 2364
Unexpected keyword argument 'ssl_context'` · Issue #2364 · boto/boto3
ubuntu@ip-############:~$ python3 mixer_s3.py Traceback (most recent call last): File "/home/ubuntu/.local/lib/python3.7/site-packages/botocore/httpsession.py", line 263, in send chunked=self._chunked(request.headers), File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 549, in urlopen conn = self._get_conn(timeout=pool_timeout) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 251, in _get_conn return conn or self._new_conn() File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 212, in _new_conn strict=self.strict, **self.conn_kw) File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 121, in init _HTTPConnection.init(self, *args, **kw) TypeError: init() got an unexpected keyword argument 'ssl_context'
Author   ghost
🌐
OpenDev
opendev.org › openstack › oslo.service › commit › caf66be763fd8f99ccfa57a8e465aaf1b85b5fe8
Fix wsgi SSL tests for wsgi module under python 3 · caf66be763 - oslo.service - OpenDev: Free Software Needs Free Tools
Indeed, when we try to use requests ... keyword argument '_context' ``` This is due to the fact that we are in a monkey patched environment where `requests` is monkey patched too....
🌐
GitHub
github.com › spec-first › connexion › issues › 1793
Document how to run the server with the SSL context in 3.0 · Issue #1793 · spec-first/connexion
November 7, 2023 - import ssl import connexion app = connexion.FlaskApp(__name__, specification_dir="openapi/") app.add_api("api.yaml", resolver=RestyResolver('api.v1')) ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile='saved_client.crt', keyfile='saved_client.key') ssl_context.load_verify_locations(cafile='saved_ca.crt') # Run the server with the SSL context app.run(ssl_context=ssl_context, host=os.environ.get("SELF_HOST"), port=int(os.environ.get("SELF_PORT")))
Author   winggo12
🌐
Redash
discuss.redash.io › support › self hosted redash support
Ssl_wrap_socket_with_ocsp() got an unexpected keyword argument 'key_password' when using SAML in 9.9.0-alpha
January 7, 2020 - Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__ return self.wsgi_app(environ, start_response) [..] File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 394, in connect ssl_context=context, TypeError: ssl_wrap_socket_with_ocsp() got an unexpected keyword argument 'key_password'
🌐
Google Cloud
googlecloudcommunity.com › gc › Databases › Google-cloud-sql-Postgres-python-connector-ssl-error › m-p › 548800
Solved: Re: Google cloud sql Postgres python connector ssl... - Google Cloud Community
July 28, 2023 - with Connector(ssl_context=ssl_context) as connector: TypeError: Connector.__init__() got an unexpected keyword argument 'ssl_context' ... def getconn(): # Create an SSL context with safe default settings ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) # Load the CA certificate bundle file ssl_context.load_verify_locations(cafile='/Users/Downloads/ca-bundle.crt') with Connector() as connector: # Wrap the connector with SSL using the created SSL context connector.ssl_wrap_socket( ssl_context=ssl_context, server_hostname=instance_connection_name ) conn = connector.connect( instance_connection_name, "pg8000", user=db_user, password=db_pass, db=db_name, ip_type=IPTypes.PUBLIC ) return conn
🌐
Cisco Community
community.cisco.com › t5 › network-security › estreamer-to-microsoft-sentinel › td-p › 5192013
Estreamer to Microsoft Sentinel - Cisco Community
September 9, 2024 - Tring to get an on-prem virtual FMC server and Azure based Ubuntu box to operate as estreamer in CEF. Cannot get past the following error TypeError: SSLContext.wrap_socket() got an unexpected keyword argument 'keyfile' - full output below. Ubuntu 24.04 LTS Kernel: Linux 6.8.0-1013-azure Architecture...
🌐
Red Hat
bugzilla.redhat.com › show_bug.cgi
1384491 – TypeError: __init__() got an unexpected keyword argument 'server_hostname'
Red Hat Bugzilla – Bug 1384491 · This site requires JavaScript to be enabled to function correctly, please enable it · Privacy Contact FAQ Legal