apache-kafkaopensslldapdata-distribution-service

libldap.so.2 undefined symbol: EVP_md2, version OPENSSL_3.0.0


Context

I am trying to build a small demo application that passes data between RTI DDS Connext topics and Kafka topics. This involves running RTI's Routing Service utility, which in turn runs a kafka adapter also provided by RTI.

When I run the routing service application, I get the following error: librtikafkaadapter.so: /lib64/libldap.so.2: undefined symbol: EVP_md2, version OPENSSL_3.0.0

Question

How do I get this kafka adapter to work with the version of OpenSSL that I have on my OS (Rocky 9.5, OpenSSL 3.2.2)?

What I've Tried

Through many hours of googling, I have been lead to believe that my OS (Rocky 9.5) uses a version of OpenSSL that has deprecated the use of this EVP_md2 algorithm.

To fix this, I edited the /etc/ssl/openssl.cnf file to enable legacy providers, and verified in two different ways that legacy support is enabled:

Firstly, I run openssl list -providers and see the support is activated:

Providers:
  default
    name: OpenSSL Default Provider
    version: 3.2.2
    status: active
  legacy
    name: OpenSSL Legacy Provider
    version: 3.2.2
    status: active

Next, I have verified the dependency chain between libldap.so.2 and libcrypto.so.3: The dependency is met at the file level, and we see that libcrypto exports the EVP_md2 function:

[loggerhead@localhost ~]$ ldd /lib64/libldap.so.2 | grep libcrypto
    libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007f5bfb000000)

[loggerhead@localhost ~]$ nm -D /lib64/libldap.so.2 | grep md2
                 U EVP_md2@OPENSSL_3.0.0

[loggerhead@localhost ~]$ nm -D /lib64/libcrypto.so.3 | grep md2
00000000001aac70 T EVP_md2@@OPENSSL_3.0.0

Third, I found (thanks google) that I can call the md2 algorithm from the command line: echo -n "aaa" | openssl md2 -provider legacy

I then re-built the RTI kafka adapter library, but still receive the same error. I don't understand why I can run this md2 algorithm from the command line but that the code for this adapter can't call it.

I have also tried installing a so-called compatibility engine compat-openssl11 that is supposed to provide backwards compatibility for old applications running on systems with newer versions of OpenSSL, but that also did not work.

Any help would be appreciated.


Solution

  • You're misreading the error message. It's not an OpenSSL error. It's a Linux library (dynamic linker) error.

    Providers only help with programs that use the "new" OpenSSL 3.x method of retrieving an algorithm by its string name, e.g. using algo = EVP_MAC_fetch(...) and similar functions.

    But the libldap.so that you have is using the older OpenSSL interface style, where the list of supported algorithms was fixed at compile time, and the library provided individual functions to retrieve each algorithm – such as algo = EVP_md4(), EVP_sha1(), and so on. If OpenSSL was compiled without support for some algorithm, then the corresponding function would simply not exist in the library.

    (Even then, it is possible for a program to look up library symbols at runtime using dlsym() and handle their absence somehow. But from the error message it's clear that libldap.so doesn't do that – those symbols are a hard dependency. Which is how most software uses libraries, anyway.)

    So the only way to make that libldap.so.2 work is to point it at a different OpenSSL libcrypto.so which has been compiled with support for that algorithm, e.g. using LD_LIBRARY_PATH= to have it load libraries from elsewhere than the default paths, or even LD_PRELOAD= in a pinch.

    Or to rebuild libldap so that it detects the absence of 'EVP_md2' at configure time and doesn't build code that would link to it.

    (You can run nm -D on libcrypto.so to see its exports 'T', and on libldap.so to see its required imports 'U'. The libldap I have on a different distribution only links to EVP_md4/EVP_md5/etc, so I'm sure that support for EVP_md2 is compile-time optional.)

    The question is, though, where did that libldap.so come from? And is the kafka adapter supposed to be using it? Surely it's not the one provided by Rocky, as the distribution's package manager should have ensured that the correct dependencies (e.g. an older libcrypto) were present. Did it come bundled with the Kafka adapter? Or is it a leftover from some different project? Either way, before anything else, I'd try to find out where the /lib64/libldap.so.2 library came from (rpm -q --whatprovides or similar) and whether it should be there at all.