5

As I'm writing code to install on a target machine, I was wondering about the dependencies and noticed that there were no openssl library needed. I wondered because I know I am using OpenSSL:

#include <openssl/md5.h>

...
MD5(a, b, c);
...

To my surprise, it seems that we only get linked against libc. Is MD5 really implemented in libc and not in some libssl library?


objdump gives me the info about the linked library:

Dynamic Section:
  NEEDED               libQtCore.so.4
  NEEDED               libstdc++.so.6
  NEEDED               libgcc_s.so.1
  NEEDED               libc.so.6
  SONAME               libcontent.so

As suggested by noloader I tried with ldd and still fail to see a library that would make sense for MD5. libcontent.so is directly using MD5()...

ldd ../BUILD/snapwebsites/plugins/content/libcontent.so 
    linux-vdso.so.1 =>  (0x00007fff4f3ff000)
    libQtCore.so.4 => /usr/lib/x86_64-linux-gnu/libQtCore.so.4 (0x00007ff37ad0f000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff37aa0c000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff37a7f5000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff37a42c000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff37a20f000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007ff379ff7000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff379df3000)
    libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007ff379af7000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ff3798ee000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff3795e9000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff37b5e5000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007ff3793a9000)

Also, just to make sure, I tried nm on that content library and I can see the MD5 entry:

                 w _ITM_registerTMCloneTable
00000000003c9468 d __JCR_END__
00000000003c9468 d __JCR_LIST__
                 w _Jv_RegisterClasses
                 U MD5                       <---- it's here...
                 U memcmp@@GLIBC_2.2.5
                 w pthread_cancel
                 U pthread_mutex_destroy@@GLIBC_2.2.5
Alexis Wilke
  • 15,168
  • 8
  • 60
  • 116
  • How did you learn that this binary is only linked against libc? –  Feb 21 '14 at 23:44
  • What will you be using MD5 for? – ErstwhileIII Feb 21 '14 at 23:44
  • @delnan, I made an update with the output of objdump -x. – Alexis Wilke Feb 21 '14 at 23:54
  • @ErstwhileIII, I already use it. I am working on a CMS for websites. When you upload a file, I compute the MD5 and use that as the key in the Cassandra database (the ID, if you wish). It works just fine, I'm just surprised that a corresponding .so is not present. – Alexis Wilke Feb 21 '14 at 23:56
  • @Alexis - forgive my ignorance here... Did the program successfully link? – jww Feb 22 '14 at 19:11
  • 2
    This is only a library, `libcontent.so` , strictly speaking it doesn't need to link to a library that provides MD5(). But whatever application that loads this library needs to. – nos Feb 22 '14 at 19:58
  • I just noticed @Alexis - `MD5(a, b, c, d);` is not OpenSSL's `MD5`. OpenSSL's `MD5` has three parameters, not four. Try right clicking in QT Designer (I think that's what its called), and "Go to definition". It might be a macro provided by QT to wrap a QT implementation. – jww Feb 22 '14 at 22:03
  • @noloader, sorry about that, I verified my code, there are only 3 parameters. So that's the OpenSSL version. Also QtCore does not link against any of the OpenSSL libraries, but they probably have their own implementation (so they can compile their code on more systems.) – Alexis Wilke Feb 23 '14 at 05:04

1 Answers1

5

In which library is the MD5() function?

The OpenSSL library. Link to libcrypto. See md5(3).


Is MD5 really implemented in libc and not in some libssl library?

Well, its not in Ubuntu's libc:

$ nm -D  /lib/x86_64-linux-gnu/libc.so.6 | grep -i md5
$

And it is in OpenSSL's libcrypto:

$ nm -D /usr/lib/x86_64-linux-gnu/libcrypto.so | grep MD5
0000000000066840 T MD5
0000000000066640 T MD5_Final
0000000000066790 T MD5_Init
0000000000066630 T MD5_Transform
0000000000066420 T MD5_Update

The T means the symbol (MD5) is defined in the TEXT section and its exported. A t means the symbol is defined in the TEXT section, but its not exported so you cannot link against it (think GCC's visibility=private or a static declaration).

If you get a U, then that means the symbol is required but undefined and a library will have to provide it.


#include <openssl/md5.h>

...
MD5(a, b, c, d);

MD5(a, b, c, d); is not OpenSSL's MD5. OpenSSL's MD5 has three parameters, not four.


objdump gives me the info about the linked library

ldd might give you different results. Its what I use to check dependencies (and I don't use objdump):

$ cat t.c
#include <openssl/md5.h>

int main(int argc, char* argv[])
{
    const char password[] = "password";
    char hash[MD5_DIGEST_LENGTH];    
    MD5(password, sizeof(password), hash);

    return 0;
}

$ gcc t.c -o t.exe -lcrypto
$ ldd t.exe 
    linux-vdso.so.1 =>  (0x00007fff435ff000)
    libcrypto.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007fbaff01b000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbafec90000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fbafea8b000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fbafe874000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fbaff429000)

And t.exe's unresolved symbol:

$ nm t.exe | grep MD5
    U MD5@@OPENSSL_1.0.0
Jandellis
  • 35
  • 2
  • 8
jww
  • 83,594
  • 69
  • 338
  • 732
  • I still don't see libcrypto in the list of dependencies. Could it be that because this is a .so, it will resolve it at run time and if the main process is linked against libcrypto then it will all work just fine? (I just checked and the main app is linked against libcrypto.so, so that would be the answer! what do you think?) – Alexis Wilke Feb 22 '14 at 04:47
  • The `U` in `U MD5` means the symbol is undefined and a library must provide it. Try dumping `libQtCore` (`nm -D`) to see if `libQtCore` provides it; or try dumping the dependencies of `libQtCore` to see if `libQtCore` links against OpenSSL's `libcrypto.so`. – jww Feb 22 '14 at 19:10
  • Note that I load that .so using ldopen(). I looked at all the libraries that are linked against that .so and none have the `libcrypto.so` file in them. However, it is there in the main application. Using the lazy linking mode of ldopen(), I think it is capable of finding that library from the linked libraries of the main application... I guess that's okay, only it's not what I'd call safe (because that library could be removed from the main application and then the lazy load works, but if I call that function, it's going to fail saying it could not resolve the symbol at execution time.) – Alexis Wilke Feb 23 '14 at 05:01