Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenSSL Linking undefined reference 'EVP_MD_CTX_new' and '...fre'

I'm trying to use the hash algorithms provided by the openssl library. I have openssl and libssl-dev installed. The version is 1.1.0f. I try to run the example code of the openssl.org site:

#include <stdio.h>

#include <openssl/evp.h>

int main(int argc, char *argv[]){
EVP_MD_CTX *mdctx;
const EVP_MD *md;
char mess1[] = "Test Message\n";
char mess2[] = "Hello World\n";
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len, i;

if(!argv[1]) {
    printf("Usage: mdtest digestname\n");
    exit(1);
 }

md = EVP_get_digestbyname(argv[1]);

if(!md) {
    printf("Unknown message digest %s\n", argv[1]);
    exit(1);
}

mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, mess1, strlen(mess1));
EVP_DigestUpdate(mdctx, mess2, strlen(mess2));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);

printf("Digest is: ");
for (i = 0; i < md_len; i++)
    printf("%02x", md_value[i]);
printf("\n");

exit(0);
}

I try to compile this with:

 gcc digest_example.c -lcrypto -lssl

And the compiler gives the error:

digest_example.c:(.text+0xbc): undefined reference to `EVP_MD_CTX_new'
digest_example.c:(.text+0x138): undefined reference to `EVP_MD_CTX_free'
collect2: error: ld returned 1 exit status

And honestly, I'm clueless. I installed and reinstalled OpenSSL 2 times from the website by compiling it. Additionally, all the other commands make no problem. Just these two. Do I have to use other libraries when linking?

Thanks for your help.

like image 817
K. Math Avatar asked Oct 16 '17 10:10

K. Math


2 Answers

You seem to be using an older version of openssl (< 1.1.0). Maybe you have downloaded and installed the newer version, but your linker seems to find and use an older version of your openssl library.

EVP_MD_CTX_new() in 1.1.0 has replaced EVP_MD_CTX_create() in 1.0.x.

EVP_MD_CTX_free() in 1.1.0 has replaced EVP_MD_CTX_destroy() in 1.0.x.

You might try to use the older versions of these functions or make sure, that your linker really uses the >= 1.1.0 version of the openssl library.

like image 140
Ctx Avatar answered Dec 08 '22 10:12

Ctx


The version is 1.1.0f. I try to run the example code of the openssl.org site ...

I installed and reinstalled OpenSSL 2 times from the website by compiling it ...

I believe OpenSSL 1.1.0 installs into /usr/local/ssl. Headers are located at /usr/local/ssl/include and libs are located at /usr/local/ssl/lib. You need to compile and link with:

gcc -I /usr/local/ssl digest_example.c -Wl,-L,/usr/local/lib -lssl -lcrypto

In fact, because Linux paths are f**k'd up, your need to add an RPATH so you link to the proper libraries at runtime (not compile time). So you really need the following because Linux still can't get it right after 30 years or so:

gcc -I /usr/local/ssl digest_example.c -Wl,-rpath,/usr/local/lib -Wl,-L,/usr/local/lib -lssl -lcrypto

You still need to get the order of the libraries right because LD is a single pass linker.

Your command linked with the system's version of OpenSSL, which is 1.0.2.

 gcc digest_example.c -lcrypto -lssl

The order of the libraries was wrong, however. The libraries should have been called out as -lssl -lcrypto.

like image 36
jww Avatar answered Dec 08 '22 09:12

jww