From bb7d7a803665005cc72ad68a388e9e937ff3d2f6 Mon Sep 17 00:00:00 2001 From: Josef Schlehofer Date: Sat, 23 Mar 2019 21:02:17 +0100 Subject: [PATCH] support for mbedTLS --- INSTALL.rst | 4 ++-- doc/thread-safety.rst | 2 +- setup.py | 28 +++++++++++++++++++++------- src/module.c | 6 ++++-- src/pycurl.h | 7 ++++++- src/threadsupport.c | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 73 insertions(+), 13 deletions(-) diff --git a/INSTALL.rst b/INSTALL.rst index 8ad8b4f..da70d25 100644 --- a/INSTALL.rst +++ b/INSTALL.rst @@ -53,7 +53,7 @@ It will then fail at runtime as follows:: To fix this, you need to tell ``setup.py`` what SSL backend is used:: - python setup.py --with-[openssl|gnutls|nss] install + python setup.py --with-[openssl|gnutls|nss|mbedtls] install Note: as of PycURL 7.21.5, setup.py accepts ``--with-openssl`` option to indicate that libcurl is built against OpenSSL. ``--with-ssl`` is an alias @@ -85,7 +85,7 @@ environment variable:: The same applies to the SSL backend, if you need to specify it (see the SSL note above):: - export PYCURL_SSL_LIBRARY=[openssl|gnutls|nss] + export PYCURL_SSL_LIBRARY=[openssl|gnutls|nss|mbedtls] easy_install pycurl diff --git a/doc/thread-safety.rst b/doc/thread-safety.rst index 5ba3f3e..ae2b9e5 100644 --- a/doc/thread-safety.rst +++ b/doc/thread-safety.rst @@ -21,7 +21,7 @@ For Python programs using PycURL, this means: Python code *outside of a libcurl callback for the PycURL object in question* is unsafe. -PycURL handles the necessary SSL locks for OpenSSL/LibreSSL, GnuTLS and NSS. +PycURL handles the necessary SSL locks for OpenSSL/LibreSSL, GnuTLS, NSS and mbedTLS. A special situation exists when libcurl uses the standard C library name resolver (i.e., not threaded nor c-ares resolver). By default libcurl diff --git a/setup.py b/setup.py index e1e6925..5ab437f 100644 --- a/setup.py +++ b/setup.py @@ -143,6 +143,7 @@ class ExtensionConfiguration(object): '--with-ssl': self.using_openssl, '--with-gnutls': self.using_gnutls, '--with-nss': self.using_nss, + '--with-mbedtls': self.using_mbedtls, } def detect_ssl_option(self): @@ -152,20 +153,20 @@ class ExtensionConfiguration(object): if option != other_option: if scan_argv(self.argv, other_option) is not None: raise ConfigurationError('Cannot give both %s and %s' % (option, other_option)) - + return option def detect_ssl_backend(self): ssl_lib_detected = False - + if 'PYCURL_SSL_LIBRARY' in os.environ: ssl_lib = os.environ['PYCURL_SSL_LIBRARY'] - if ssl_lib in ['openssl', 'gnutls', 'nss']: + if ssl_lib in ['openssl', 'gnutls', 'nss', 'mbedtls']: ssl_lib_detected = True getattr(self, 'using_%s' % ssl_lib)() else: raise ConfigurationError('Invalid value "%s" for PYCURL_SSL_LIBRARY' % ssl_lib) - + option = self.detect_ssl_option() if option: ssl_lib_detected = True @@ -194,6 +195,10 @@ class ExtensionConfiguration(object): self.using_nss() ssl_lib_detected = True break + if arg[2:] == 'mbedtls': + self.using_nss() + ssl_lib_detected = True + break if not ssl_lib_detected and len(self.argv) == len(self.original_argv) \ and not os.environ.get('PYCURL_CURL_CONFIG') \ @@ -201,7 +206,7 @@ class ExtensionConfiguration(object): # this path should only be taken when no options or # configuration environment variables are given to setup.py ssl_lib_detected = self.detect_ssl_lib_on_centos6() - + self.ssl_lib_detected = ssl_lib_detected def curl_config(self): @@ -301,7 +306,7 @@ class ExtensionConfiguration(object): if errtext: msg += ":\n" + errtext raise ConfigurationError(msg) - + # hack self.sslhintbuf = sslhintbuf @@ -327,7 +332,7 @@ specify the SSL backend manually.''') self.library_dirs.append(arg[2:]) else: self.extra_link_args.append(arg) - + if not self.libraries: self.libraries.append("curl") @@ -354,6 +359,9 @@ specify the SSL backend manually.''') elif ssl_version.startswith('NSS/'): self.using_nss() ssl_lib_detected = True + elif ssl_version.startswith('mbedTLS/'): + self.using_mbedtls() + ssl_lib_detected = 'mbedtls' return ssl_lib_detected def detect_ssl_lib_on_centos6(self): @@ -505,6 +513,11 @@ specify the SSL backend manually.''') self.libraries.append('ssl3') self.define_macros.append(('HAVE_CURL_SSL', 1)) + def using_mbedtls(self): + self.define_macros.append(('HAVE_CURL_MBEDTLS', 1)) + self.libraries.append('mbedtls') + self.define_macros.append(('HAVE_CURL_SSL', 1)) + def get_bdist_msi_version_hack(): # workaround for distutils/msi version requirement per # epydoc.sourceforge.net/stdlib/distutils.version.StrictVersion-class.html - @@ -871,6 +884,7 @@ PycURL Unix options: --with-ssl legacy alias for --with-openssl --with-gnutls libcurl is linked against GnuTLS --with-nss libcurl is linked against NSS + --with-mbedtls libcurl is linked against mbedTLS ''' windows_help = '''\ diff --git a/src/module.c b/src/module.c index 2331ae8..7fdb25a 100644 --- a/src/module.c +++ b/src/module.c @@ -328,7 +328,7 @@ initpycurl(void) PyObject *collections_module = NULL; PyObject *named_tuple = NULL; PyObject *arglist = NULL; - + assert(Curl_Type.tp_weaklistoffset > 0); assert(CurlMulti_Type.tp_weaklistoffset > 0); assert(CurlShare_Type.tp_weaklistoffset > 0); @@ -355,6 +355,8 @@ initpycurl(void) runtime_ssl_lib = "gnutls"; } else if (!strncmp(vi->ssl_version, "NSS/", 4)) { runtime_ssl_lib = "nss"; + } else if (!strncmp(vi->ssl_version, "mbedTLS/", 2)) { + runtime_ssl_lib = "mbedtls"; } else { runtime_ssl_lib = "none/other"; } @@ -461,7 +463,7 @@ initpycurl(void) /* constants for ioctl callback argument values */ insint_c(d, "IOCMD_NOP", CURLIOCMD_NOP); insint_c(d, "IOCMD_RESTARTREAD", CURLIOCMD_RESTARTREAD); - + /* opensocketfunction return value */ insint_c(d, "SOCKET_BAD", CURL_SOCKET_BAD); diff --git a/src/pycurl.h b/src/pycurl.h index 65290f7..2294cb8 100644 --- a/src/pycurl.h +++ b/src/pycurl.h @@ -174,6 +174,11 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size); # define COMPILE_SSL_LIB "gnutls" # elif defined(HAVE_CURL_NSS) # define COMPILE_SSL_LIB "nss" +# elif defined(HAVE_CURL_MBEDTLS) +# include +# define PYCURL_NEED_SSL_TSL +# define PYCURL_NEED_MBEDTLS_TSL +# define COMPILE_SSL_LIB "mbedtls" # else # ifdef _MSC_VER /* sigh */ @@ -190,7 +195,7 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size); /* since we have no crypto callbacks for other ssl backends, * no reason to require users match those */ # define COMPILE_SSL_LIB "none/other" -# endif /* HAVE_CURL_OPENSSL || HAVE_CURL_GNUTLS || HAVE_CURL_NSS */ +# endif /* HAVE_CURL_OPENSSL || HAVE_CURL_GNUTLS || HAVE_CURL_NSS || HAVE_CURL_MBEDTLS */ #else # define COMPILE_SSL_LIB "none/other" #endif /* HAVE_CURL_SSL */ diff --git a/src/threadsupport.c b/src/threadsupport.c index 6ca07f5..51abffd 100644 --- a/src/threadsupport.c +++ b/src/threadsupport.c @@ -232,6 +232,45 @@ pycurl_ssl_cleanup(void) } #endif +/* mbedTLS */ + +#ifdef PYCURL_NEED_MBEDTLS_TSL +static int +pycurl_ssl_mutex_create(void **m) +{ + if ((*((PyThread_type_lock *) m) = PyThread_allocate_lock()) == NULL) { + return -1; + } else { + return 0; + } +} + +static int +pycurl_ssl_mutex_destroy(void **m) +{ + PyThread_free_lock(*((PyThread_type_lock *) m)); + return 0; +} + +static int +pycurl_ssl_mutex_lock(void **m) +{ + return !PyThread_acquire_lock(*((PyThread_type_lock *) m), 1); +} + +PYCURL_INTERNAL int +pycurl_ssl_init(void) +{ + return 0; +} + +PYCURL_INTERNAL void +pycurl_ssl_cleanup(void) +{ + return; +} +#endif + /************************************************************************* // CurlShareObject **************************************************************************/ -- 2.17.0.windows.1