Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can wolfssl context be used with requests http adaptor? #10

Open
VeNoMouS opened this issue Aug 4, 2019 · 4 comments
Open

Can wolfssl context be used with requests http adaptor? #10

VeNoMouS opened this issue Aug 4, 2019 · 4 comments
Assignees

Comments

@VeNoMouS
Copy link

VeNoMouS commented Aug 4, 2019

#!/usr/bin/python3
import requests
import wolfssl

from collections import OrderedDict
from requests.adapters import HTTPAdapter


class CipherSuiteAdapter(HTTPAdapter):

    def __init__(self, **kwargs):

        wolfssl.WolfSSL.enable_debug()
        self.ssl_context = wolfssl.SSLContext(wolfssl.PROTOCOL_TLSv1_2)
        self.ssl_context.verify_mode = wolfssl.CERT_NONE
        self.ssl_context.set_ciphers('ECDHE-RSA-AES128-GCM-SHA256')

        super(CipherSuiteAdapter, self).__init__(**kwargs)

    # ------------------------------------------------------------------------------- #

    def init_poolmanager(self, *args, **kwargs):
        kwargs['ssl_context'] = self.ssl_context
        return super(CipherSuiteAdapter, self).init_poolmanager(*args, **kwargs)

    # ------------------------------------------------------------------------------- #

    def proxy_manager_for(self, *args, **kwargs):
        kwargs['ssl_context'] = self.ssl_context
        return super(CipherSuiteAdapter, self).proxy_manager_for(*args, **kwargs)

# ------------------------------------------------------------------------------- #


session = requests.session()
session.mount('https://', CipherSuiteAdapter())
session.headers = OrderedDict([
    ("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0"),
    ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"),
    ("Accept-Language", "en-US,en;q=0.5"),
    ("Accept-Encoding", "gzip, deflate")
])

print(session.get('https://somewebsite/', verify=False).status_code)

The following results in..

Traceback (most recent call last):
  File "./wolf.py", line 54, in <module>
    print(session.get('https://somewebsite', verify=False).status_code)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 546, in get
    return self.request('GET', url, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 603, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 344, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 843, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connection.py", line 370, in connect
    ssl_context=context)
  File "/usr/local/lib/python3.7/dist-packages/urllib3/util/ssl_.py", line 355, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/local/lib/python3.7/dist-packages/wolfssl/__init__.py", line 243, in wrap_socket
    _context=self, server_hostname=server_hostname)
  File "/usr/local/lib/python3.7/dist-packages/wolfssl/__init__.py", line 396, in __init__
    self._context.use_sni(server_hostname)
  File "/usr/local/lib/python3.7/dist-packages/wolfssl/__init__.py", line 263, in use_sni
    server_hostname, len(server_hostname))
TypeError: initializer for ctype 'void *' must be a cdata pointer, not str
@VeNoMouS
Copy link
Author

VeNoMouS commented Aug 4, 2019

applying the PR 8560c65 we get a new error

Traceback (most recent call last):
  File "./wolf.py", line 54, in <module>
    print(session.get('https://somewebsite', verify=False).status_code)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 546, in get
    return self.request('GET', url, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 603, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 373, in _make_request
    conn.sock.settimeout(read_timeout)
AttributeError: 'SSLSocket' object has no attribute 'settimeout'

@VeNoMouS
Copy link
Author

VeNoMouS commented Aug 4, 2019

Monkey patching the above, just creates another issue..

    httplib_response = conn.getresponse()
  File "/usr/lib/python3.7/http/client.py", line 1317, in getresponse
    response = self.response_class(self.sock, method=self._method)
  File "/usr/lib/python3.7/http/client.py", line 234, in __init__
    self.fp = sock.makefile("rb")
AttributeError: 'SSLSocket' object has no attribute 'makefile'

So I guess this is not capable of being used in requests ... too many incompatibilities

@kaleb-himes
Copy link

Hi @VeNoMouS,

Thank you so much for reaching out to wolfSSL with your questions. For best response times feel free to email us anytime at support@wolfssl.com.

Can you tell us a bit about the project you are interested in using wolfSSL in and end goals of that project? I can confirm we have not tested using wolfSSL with https://pypi.org/project/requests/ yet. Would you like us to add it to our desired features list?

Desired features are features we work on for free between funded efforts. Desired features have no associated timeline but they can be accelerated at anytime if a need arrises, just let us know you'd like to accelerate a given feature and we can put you in touch with the resources to help get that done!

Warmest Regards,

K

@nkosmynin
Copy link

nkosmynin commented Dec 12, 2023

applying the PR 8560c65 we get a new error

Traceback (most recent call last):
  File "./wolf.py", line 54, in <module>
    print(session.get('https://somewebsite', verify=False).status_code)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 546, in get
    return self.request('GET', url, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 603, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py", line 373, in _make_request
    conn.sock.settimeout(read_timeout)
AttributeError: 'SSLSocket' object has no attribute 'settimeout'

I am trying also to use wolfssl in standard HTTPServer, and received similar error.
To correct it, I added missing method to class SSLSocket and rebuilt wolfssl-py:
def makefile(self,mode='r', buffering=None, *, encoding=None, errors=None, newline=None): return self._sock.makefile(mode, buffering)
After that lib started to work, however, another issue encountered - handshake and writing to socket is performed properly, but reading from socket does not apply ciphering. I think it can be difficult to overcome. It seems that context is properly passed, but when standard socket library is trying to read from buffered I/O, it uses standard socket class instead of WolfSSL socket.
I was testing using Python 3.9 and 3.11, not sure if going to higher version would help.

P.S. Apparently, we cannot call self._sock.makefile(), instead a copy of socket.makefile() shall be added and adapted as override method in class SSLSocket

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants