rbit / pydtls

Datagram Transport Layer Security for Python
Apache License 2.0
72 stars 45 forks source link

"DTLS_server_method" not found in libssl.1.0.0 #15

Open jyotirajsharma opened 7 years ago

jyotirajsharma commented 7 years ago

I have installed "pip install Dtls" in my raspberry pi3. Now the problem is: Problem: Note: Looks like, pyDTLS that installed libssl.1.0.0 which does not have "DTLS_server_method". May be it is required to install libssl.1.0.2 from pyDtls itself. How to do this ?

I am getting following error while trying to use your DTLS method for my test_secure.py COAP method. Traceback (most recent call last): File "test_secure.py", line 23, in from dtls.wrapper import wrap_server, wrap_client File "/usr/local/lib/python2.7/dist-packages/dtls/init.py", line 63, in from patch import do_patch File "/usr/local/lib/python2.7/dist-packages/dtls/patch.py", line 44, in from sslconnection import SSLConnection, PROTOCOL_DTLS, PROTOCOL_DTLSv1, PROTOCOL_DTLSv1_2 File "/usr/local/lib/python2.7/dist-packages/dtls/sslconnection.py", line 60, in from x509 import _X509, decode_cert File "/usr/local/lib/python2.7/dist-packages/dtls/x509.py", line 34, in from openssl import File "/usr/local/lib/python2.7/dist-packages/dtls/openssl.py", line 811, in ((c_char_p, "ret"), (c_int, "nid")), True, None), File "/usr/local/lib/python2.7/dist-packages/dtls/openssl.py", line 642, in map(lambda x: _make_function(x), ( File "/usr/local/lib/python2.7/dist-packages/dtls/openssl.py", line 562, in _make_function for i in args[1:])) AttributeError: /usr/lib/arm-linux-gnueabihf/libssl.so.1.0.0: undefined symbol: DTLS_server_method

rbit commented 7 years ago

PyDTLS did not install OpenSSL (including the file libssl.1.0.0) on your machine. OpenSSL dll's are part of the PyDTLS installation tree on Windows only. Linux platforms usually provide a sufficiently recent version of OpenSSL, and this must be available before PyDTLS can run.

It is possible that the OpenSSL version on your machine is older than 1.0.2. But you can't tell that from the shared object's file name. You may want to try to upgrade your OpenSSL version using your package manager. If that doesn't work, you could build OpenSSL yourself, and then put it into a place in the file system where the PyDTLS OpenSSL library loader will find it.

jyotirajsharma commented 7 years ago

But you are linking to libssl1.0.0 from /dtls/openssl.py as per above traceback from dtls itself.

Openssl version is 1.0.2g in my Raspberry pi3 machine but libssl1.0.0 is shown whenever i install pyDtls.

How to fix this?

rbit commented 7 years ago
$ ldd /usr/bin/openssl
    linux-vdso.so.1 =>  (0x00007ffe8b1c5000)
    libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f3ea9b0a000)
    libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f3ea96c6000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3ea92fc000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f3ea90f8000)
    /lib64/ld-linux-x86-64.so.2 (0x0000555a734ff000)
$ /usr/bin/openssl version
OpenSSL 1.0.2g  1 Mar 2016

Make sure that the shared object libssl.so.1.0.0 that is used by your OpenSSL installation (which is version 1.0.2g, as you say) is that same as the one your system loader delivers when PyDTLS opens it (openssl.py in PyDTLS opens the shared object without path prefix). If your /usr/bin/openssl is statically linked, then install an OpenSSL version that uses shared objects instead.

jyotirajsharma commented 7 years ago
How to link libssl.so.1.0.0 ?
My system config is:
//libssl.so.1.0.0 is present at this path...
pi@raspberrypi:/usr/lib/arm-linux-gnueabihf $ ls libssl*
libssl3.so  libssl.so.1.0.0
//
 $ ldd /usr/bin/openssl
        linux-vdso.so.1 (0x7ed9c000)
        /usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76f52000)
        libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76f2b000)
        libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76dea000)
        /lib/ld-linux-armhf.so.3 (0x54b13000)

//
pi@raspberrypi:~ $ /usr/bin/openssl version
OpenSSL 1.0.2g  1 Mar 2016

As per below code, does 'pyDtls' not link to 'else' part ? if sys.platform.startswith('win'): dll_path = path.abspath(path.dirname(file)) cryptodll_path = path.join(dll_path, "libeay32.dll") ssldll_path = path.join(dll_path, "ssleay32.dll") libcrypto = CDLL(cryptodll_path) libssl = CDLL(ssldll_path) else: libcrypto = CDLL("libcrypto.so.1.0.0") libssl = CDLL("libssl.so.1.0.0")

rbit commented 7 years ago

Yes, the 'else' portion is used on non-Windows platforms. libssl.so.1.0.0 refers to OpenSSL 1.0.2 wherever that version of OpenSSL is installed.

As your output shows, the version of OpenSSL in /usr/bin is not dynamically linked against libssl.so and libcrypto.so. So there is nothing there that PyDTLS can use. You need a version of OpenSSL that is dynamically linked.

It's also worth noting that since your executing flow proceeds up to the point of trying to import a particular symbol (DTLS_server_method), some version of the shared libraries must have been successfully opened. But the version of /usr/bin/openssl you show above is not using those shared libraries. So it looks like you've got more than one OpenSSL version installed on your system - one being the statically linked /usr/bin/openssl and then some shared libraries, perhaps of an older version, that PyDTLS ends up opening.

jyotirajsharma commented 7 years ago

Now, I understood. But I installed OpenSSL many times but it is not linking dynamically. I am sorry to ask this but do you know how to link it dynamically ? Any link to install openssl which links dynamically will be appreciated ?

rbit commented 7 years ago

I can't answer your question because I know nothing about your platform. You may want to ask in some community forum how you can install a recent dynamically linked version of OpenSSL. And, as I mentioned before, if you can't find an answer to that question, then you can download the OpenSSL source distribution, and then follow the build and install instructions to create your own version. You'll probably want to uninstall the existing version(s) of OpenSSL from your machine before you do that to prevent confusion.

jyotirajsharma commented 7 years ago

I installed openSSL that includes shared lib, /usr/lib has now 'libssl.so.1.1' but still problem is same.

Problem here I see is AttributeError: /usr/lib/arm-linux-gnueabihf/libssl.so.1.0.0: undefined symbol: DTLS_server_method (i.e. libssl.so.1.0.0 inside /arm-liunx* does not have DTLS server method)

rbit commented 7 years ago

You installed the wrong OpenSSL series. OpenSSL currently has two active and supported series: 1.0.2 and 1.1.0. PyDTLS requires 1.0.2 (see also https://www.openssl.org/source/). And you also still have your old OpenSSL version installed in /usr/lib/arm-linux-gnueabihf/libssl.so.1.0.0. Previously I recommended that you uninstall your old version before experimenting with new versions. What is your plan for having your system's dynamic loader find the new and correct OpenSSL shared object version once you do manage to install that?

jyotirajsharma commented 7 years ago

Thanks for your comment.

I am trying to install inside /usr/lib/arm-linux-gnueabhihf as my Raspberry pi is taking openssl lib from this path. I will try following first

git clone git://git.openssl.org/openssl.git
cd openssl
$ ./config --prefix=/usr/lib/arm-linux-gnueabihf --openssldir=/usr/lib/arm-linux-gnueabihf 
make
make test
sudo make install

Do I still need to put it inside /usr/bin/openssl $./config --prefix=/usr/bin/openssl --openssldir=/usr/bin/openssl

mcfreis commented 7 years ago

Good starting point, but I think you need to pay attention to the following points:

veganjay commented 7 years ago

Here's one solution - I use a Linux server which has a different version of openssl. Rather than install a different version system-wide, I created a local build of openssl 1.0.2g I placed the libraries in /opt/openssl_1.0.2g/lib

Then before running python, set the LD_LIBRARY_PATH: export LD_LIBRARY_PATH=/opt/openssl_1.0.2g/lib

m4n3dw0lf commented 6 years ago

Try this:

pip uninstall dtls
git clone https://github.com/rbit/pydtls

edit the dtls/openssl.py file inside this repo, on the lines 68 and 69, change the version 1.0.0 to this:

    libcrypto = CDLL("libcrypto.so.1.0.2")
    libssl = CDLL("libssl.so.1.0.2")

then run: python setup.py install

if you get the error: IOError: [Errno 2] No such file or directory: 'README.rst' edit the setup.py file inside this repo, and change the line 55 to this:

        long_description = open("README.md").read()

then run the python setup.py install again...

I will open a PR for this changes...