nfcpy / nfcpy

A Python module to read/write NFC tags or communicate with another NFC device.
European Union Public License 1.1
585 stars 147 forks source link

undefined symbol : ECDH_OpenSSL on raspbian #59

Closed mortimr closed 7 years ago

mortimr commented 7 years ago

Hi, I made a script for reading and writting on ntag213 chips , and It worked fine on my computer. I wanted to use it on my raspberry pi but I can't get the nfc module loaded. Getting this error : AttributeError: /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1: undefined symbol: ECDH_OpenSSLAnd I can't find any answer on my specific problem :/ Do you have any ideas ? Thanks !

mortimr commented 7 years ago

Ok so I found that some symbols have been removed in newer versions of libcrypto, I used libcrypto.so.1.0.0 instead of libcrypto.so.1.1 and it worked ! Sorry for useless issue, hope it'll help someone else too !

nehpetsde commented 7 years ago

Glad you figured out. I've checked a recent Raspbian install and it's still on libcrypto 1.0, so there should not normally be a problem. But it's good to know there's a problem ahead, hopefully it's solvable by then. Thanks for pointing it out. I've added a safety check to prevent silent use of the newer version.

jayjohns0n commented 6 years ago

Hello, I have the same problem. Can you explain me how to change to libcrypto.so.1.0.0?

faddey-w commented 6 years ago

Faced the same issue too. Not sure that I'm using the recent version of the library, but it looks like attempt to use "ECDH_OpenSSL" is still present in current master version of nfcpy, so I think it is relevant.

Some details on my system (ask me if you need something else):

$ uname -a

Linux raspberrypi 4.14.30-v7+ #1102 SMP Mon Mar 26 16:45:49 BST 2018 armv7l GNU/Linux

$ cat /etc/os-release

NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

$ python /etc/node-red/rfid/nfcpy/examples/tagtool.py

  File "/etc/node-red/rfid/nfcpy/examples/tagtool.py", line 37, in <module>
    from cli import CommandLineInterface
  File "/etc/node-red/rfid/nfcpy/examples/cli.py", line 35, in <module>
    import nfc
  File "/etc/node-red/rfid/nfcpy/nfc/__init__.py", line 28, in <module>
    from clf import ContactlessFrontend
  File "/etc/node-red/rfid/nfcpy/nfc/clf/__init__.py", line 34, in <module>
    import nfc.llcp
  File "/etc/node-red/rfid/nfcpy/nfc/llcp/__init__.py", line 31, in <module>
    from llc import LOGICAL_DATA_LINK, DATA_LINK_CONNECTION
  File "/etc/node-red/rfid/nfcpy/nfc/llcp/llc.py", line 41, in <module>
    from . import sec
  File "/etc/node-red/rfid/nfcpy/nfc/llcp/sec.py", line 490, in <module>
    OpenSSL = OpenSSLWrapper(libcrypto)
  File "/etc/node-red/rfid/nfcpy/nfc/llcp/sec.py", line 191, in __init__
    self.crypto.ECDH_OpenSSL.restype = c_void_p
  File "/usr/lib/python2.7/ctypes/__init__.py", line 375, in __getattr__
    func = self.__getitem__(name)
  File "/usr/lib/python2.7/ctypes/__init__.py", line 380, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1: undefined symbol: ECDH_OpenSSL
faddey-w commented 6 years ago

Workaround that seems to be working for me:

I see that I have an older version of libcrypto: $ ls -la /usr/lib/arm-linux-gnueabihf/libcrypto.so.*

-rw-r--r-- 1 root root 1493272 Dec 13  2017 /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.0.2
-rw-r--r-- 1 root root 1827948 Nov  2  2017 /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1

Look at the end of file "nfcpy/nfc/llcp/sec.py": $ tail /etc/node-red/rfid/nfcpy/nfc/llcp/sec.py

                out_len = c_int(out_len)
            r = OpenSSL.crypto.EVP_EncryptUpdate(
                self._ctx, out_buf, ctypes.byref(out_len), message, msg_len)
            if r != 1: raise AssertionError("EVP_DecryptUpdate")
            return out_buf.raw[0:out_len.value] if out_buf else b''

libcrypto = ctypes.util.find_library('crypto')
if libcrypto is not None:
    OpenSSL = OpenSSLWrapper(libcrypto)

This "ctypes.util.find_library" call returns a string: "libcrypto.so.1.1". So I can just replace this call with assigning the name of older version. After edit it looks like this: $ tail /etc/node-red/rfid/nfcpy/nfc/llcp/sec.py

            r = OpenSSL.crypto.EVP_EncryptUpdate(
                self._ctx, out_buf, ctypes.byref(out_len), message, msg_len)
            if r != 1: raise AssertionError("EVP_DecryptUpdate")
            return out_buf.raw[0:out_len.value] if out_buf else b''

#libcrypto = ctypes.util.find_library('crypto')
libcrypto = 'libcrypto.so.1.0.2'
if libcrypto is not None:
    OpenSSL = OpenSSLWrapper(libcrypto)

Now it seems to be working, at least at import time - $ python /etc/node-red/rfid/nfcpy/examples/tagtool.py -h outputs help message as expected..