diff --git a/Makefile b/Makefile index a5c73f7..848087d 100644 --- a/Makefile +++ b/Makefile @@ -30,9 +30,11 @@ clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and clean-build: ## remove build artifacts + rm -fr lib/ rm -fr build/ rm -fr dist/ rm -fr .eggs/ + rm -fr wolfssl/_ffi* find . -name '*.egg-info' -exec rm -fr {} + find . -name '*.egg' -exec rm -f {} + @@ -81,7 +83,7 @@ servedocs: docs ## compile the docs watching for changes dist: clean ## builds source and wheel package python setup.py sdist - + ./make/osx/build_wheels.sh ./make/manylinux1/build_wheels.sh diff --git a/README.rst b/README.rst index f0f0acd..250b59f 100644 --- a/README.rst +++ b/README.rst @@ -13,6 +13,16 @@ library targeted at IoT, embedded, and RTOS environments primarily because of its size, speed, and feature set. It works seamlessly in desktop, enterprise, and cloud environments as well. +Compiling +========= + +The `setup.py` file covers most things you will need to do to build and install from source. As pre-requisites you will need to install either from your OS repository or pip. You'll also need the Python development package for your Python version: + +* `cffi` +* `tox` +* `pytest` + +To build a source package run `python setup.py sdist`, to build a wheel package run `python setup.py bdist_wheel`. To test the build run `tox`. The `tox` tests rely on Python 3.9 being installed, if you do not have this version we recommend using `pyenv` to install it. Installation ============ diff --git a/certs/ca-digicert-ev.pem b/certs/ca-digicert-ev.pem deleted file mode 100644 index 9e6810a..0000000 --- a/certs/ca-digicert-ev.pem +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- diff --git a/certs/ca-globalsign-r3.pem b/certs/ca-globalsign-r3.pem new file mode 100644 index 0000000..8afb219 --- /dev/null +++ b/certs/ca-globalsign-r3.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- diff --git a/setup.py b/setup.py index d6a2a62..ffb3e09 100755 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ from setuptools.command.build_ext import build_ext # Adding src folder to the include path in order to import from wolfssl -package_dir = os.path.join(os.path.dirname(__file__), "src") +package_dir = os.path.dirname(__file__) sys.path.insert(0, package_dir) import wolfssl @@ -93,7 +93,7 @@ setup( package_dir={"":package_dir}, zip_safe=False, - cffi_modules=["./src/wolfssl/_build_ffi.py:ffi"], + cffi_modules=["./wolfssl/_build_ffi.py:ffi"], keywords="wolfssl, wolfcrypt, security, cryptography", classifiers=[ diff --git a/tests/test_client.py b/tests/test_client.py index 704a656..2cccc22 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -27,12 +27,13 @@ import pytest HOST = "www.python.org" PORT = 443 -CA_CERTS = "certs/ca-digicert-ev.pem" +CA_CERTS = "certs/ca-globalsign-r3.pem" @pytest.fixture( params=["wrap_socket", "wrap_socket_with_ca", "wrap_socket_from_context", "ssl_socket"]) + def secure_socket(request, ssl_provider, tcp_socket): sock = None @@ -64,7 +65,6 @@ def secure_socket(request, ssl_provider, tcp_socket): yield sock sock.close() - def test_secure_connection(secure_socket): secure_socket.connect((HOST, PORT)) diff --git a/tox.ini b/tox.ini index ac50ab9..0faa47e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] -envlist = py27, py34, py35, py36 -skip_missing_interpreters = true +envlist = py39, pep8 +skipsdist = True [testenv] setenv = diff --git a/src/wolfssl/__about__.py b/wolfssl/__about__.py similarity index 97% rename from src/wolfssl/__about__.py rename to wolfssl/__about__.py index c2474a7..275a55f 100644 --- a/src/wolfssl/__about__.py +++ b/wolfssl/__about__.py @@ -26,7 +26,7 @@ __uri__ = "https://github.com/wolfssl/wolfssl-py" # When bumping the C library version, reset the POST count to 0 -__wolfssl_version__ = "v4.8.1-stable" +__wolfssl_version__ = "v5.1.1-stable" # We're using implicit post releases [PEP 440] to bump package version # while maintaining the C library version intact for better reference. diff --git a/src/wolfssl/__init__.py b/wolfssl/__init__.py similarity index 99% rename from src/wolfssl/__init__.py rename to wolfssl/__init__.py index 938d6e6..8f06909 100644 --- a/src/wolfssl/__init__.py +++ b/wolfssl/__init__.py @@ -138,6 +138,7 @@ class SSLContext(object): """ def __init__(self, protocol, server_side=None): + _lib.wolfSSL_Init() method = _WolfSSLMethod(protocol, server_side) self.protocol = protocol diff --git a/src/wolfssl/_build_ffi.py b/wolfssl/_build_ffi.py similarity index 94% rename from src/wolfssl/_build_ffi.py rename to wolfssl/_build_ffi.py index ccb6661..335f4d3 100644 --- a/src/wolfssl/_build_ffi.py +++ b/wolfssl/_build_ffi.py @@ -24,7 +24,8 @@ from distutils.util import get_platform from cffi import FFI -from wolfssl._build_wolfssl import wolfssl_inc_path, wolfssl_lib_path +from wolfssl._build_wolfssl import wolfssl_inc_path, wolfssl_lib_path, ensure_wolfssl_src, make, make_flags, local_path +from wolfssl.__about__ import __wolfssl_version__ as version import wolfssl._openssl as openssl import subprocess import shlex @@ -32,6 +33,8 @@ import os from ctypes import cdll from collections import namedtuple +libwolfssl_path = "" + def make_optional_func_list(libwolfssl_path, funcs): if libwolfssl_path.endswith(".so"): libwolfssl = cdll.LoadLibrary(libwolfssl_path) @@ -52,12 +55,26 @@ def make_optional_func_list(libwolfssl_path, funcs): return defined -libwolfssl_path = os.path.join(wolfssl_lib_path(), "libwolfssl.a") -if not os.path.exists(libwolfssl_path): - libwolfssl_path = os.path.join(wolfssl_lib_path(), "libwolfssl.so") +def get_libwolfssl(): + libwolfssl_path = os.path.join(wolfssl_lib_path(), "libwolfssl.a") if not os.path.exists(libwolfssl_path): - err = "Couldn't find libwolfssl under {}.".format(wolfssl_lib_path()) - raise Exception(err) + libwolfssl_path = os.path.join(wolfssl_lib_path(), "libwolfssl.so") + if not os.path.exists(libwolfssl_path): + return 0 + else: + return 1 + else: + return 1 + +def generate_libwolfssl(): + ensure_wolfssl_src(version) + prefix = local_path("lib/wolfssl/{}/{}".format( + get_platform(), version)) + make(make_flags(prefix, False)) + +if get_libwolfssl() == 0: + generate_libwolfssl() + get_libwolfssl() WolfFunction = namedtuple("WolfFunction", ["name", "native_sig", "ossl_sig"]) # Depending on how wolfSSL was configured, the functions below may or may not be @@ -175,6 +192,7 @@ cdef = """ /** * SSL/TLS Session functions */ + void wolfSSL_Init(); WOLFSSL* wolfSSL_new(WOLFSSL_CTX*); void wolfSSL_free(WOLFSSL*); @@ -276,5 +294,4 @@ for func in optional_funcs: ffi_cdef = cdef + openssl.construct_cdef(optional_funcs) ffi.cdef(ffi_cdef) -if __name__ == "__main__": - ffi.compile(verbose=True) +ffi.compile(verbose=True) diff --git a/src/wolfssl/_build_wolfssl.py b/wolfssl/_build_wolfssl.py similarity index 97% rename from src/wolfssl/_build_wolfssl.py rename to wolfssl/_build_wolfssl.py index 1d5380c..d0a137c 100644 --- a/src/wolfssl/_build_wolfssl.py +++ b/wolfssl/_build_wolfssl.py @@ -30,9 +30,8 @@ from wolfssl.__about__ import __wolfssl_version__ as version def local_path(path): """ Return path relative to the root of this project """ - current = os.path.dirname(__file__) - gparent = os.path.dirname(os.path.dirname(current)) - return os.path.abspath(os.path.join(gparent, path)) + current = os.path.abspath(os.getcwd()) + return os.path.abspath(os.path.join(current, path)) WOLFSSL_GIT_ADDR = "https://github.com/wolfssl/wolfssl.git" @@ -145,6 +144,7 @@ def make_flags(prefix, debug): # tls 1.3 flags.append("--enable-tls13") + flags.append("--enable-sslv3") # for urllib3 - requires SNI (tlsx), options (openssl compat), peer cert flags.append("--enable-tlsx") diff --git a/src/wolfssl/_methods.py b/wolfssl/_methods.py similarity index 91% rename from src/wolfssl/_methods.py rename to wolfssl/_methods.py index b5cf5a0..9fe2ded 100644 --- a/src/wolfssl/_methods.py +++ b/wolfssl/_methods.py @@ -43,7 +43,7 @@ _DYNAMIC_TYPE_METHOD = 11 def _native_free(native_object, dynamic_type): - _lib.wolfSSL_Free(native_object, _ffi.NULL, dynamic_type) + _lib.wolfSSL_Free(native_object) class WolfSSLMethod(object): # pylint: disable=too-few-public-methods @@ -72,6 +72,11 @@ class WolfSSLMethod(object): # pylint: disable=too-few-public-methods _lib.wolfTLSv1_2_server_method() if server_side else \ _lib.wolfTLSv1_2_client_method() + elif protocol == PROTOCOL_TLSv1_3: + self.native_object = \ + _lib.wolfTLSv1_3_server_method() if server_side else \ + _lib.wolfTLSv1_3_client_method() + elif protocol in [PROTOCOL_SSLv23, PROTOCOL_TLS]: self.native_object = \ _lib.wolfSSLv23_server_method() if server_side else \ diff --git a/src/wolfssl/_openssl.py b/wolfssl/_openssl.py similarity index 100% rename from src/wolfssl/_openssl.py rename to wolfssl/_openssl.py diff --git a/src/wolfssl/exceptions.py b/wolfssl/exceptions.py similarity index 100% rename from src/wolfssl/exceptions.py rename to wolfssl/exceptions.py diff --git a/src/wolfssl/utils.py b/wolfssl/utils.py similarity index 100% rename from src/wolfssl/utils.py rename to wolfssl/utils.py