Can't link OpenSSL code - c

I am trying to build an openssl simple program. Here is the complete code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "openssl/aes.h"
int main(int argc, char* argv[])
{
AES_KEY aesKey_;
unsigned char userKey_[16];
unsigned char in_[16];
unsigned char out_[16];
strcpy(userKey_,"0123456789123456");
strcpy(in_,"0123456789123456");
fprintf(stdout,"Original message: %s", in_);
AES_set_encrypt_key(userKey_, 128, &aesKey_);
AES_encrypt(in_, out_, &aesKey_);
AES_set_decrypt_key(userKey_, 128, &aesKey_);
AES_decrypt(out_, in_,&aesKey_);
fprintf(stdout,"Recovered Original message: %s", in_);
return 0;
}
I try to compile it using this command:
gcc -I/home/aleksei/openSSL0.9.8/include -o app -L . -lssl -lcrypto tema1.c
and I get this:
/tmp/ccT1XMid.o: In function `main':
tema1.c:(.text+0x8d): undefined reference to `AES_set_encrypt_key'
tema1.c:(.text+0xa7): undefined reference to `AES_encrypt'
tema1.c:(.text+0xbf): undefined reference to `AES_set_decrypt_key'
tema1.c:(.text+0xd9): undefined reference to `AES_decrypt'
collect2: ld returned 1 exit status
I am under Ubuntu 10.04. How can I get this to work ?

You may be trying to statically link, but the -L option and -lcrypto are looking for a file to link with dynamically. To statically link to a specific library, just specify your .a file on the compiler command line after all your source files.
E.g.,
gcc -I/home/aleksei/openSSL0.9.8/include -o app tema1.c ./libcrypto.a

For those of you who have this same problem but are using Windows, Mingw and this OpenSSL for Windows (at this time: Win32 OpenSSL v1.0.2a). You need to link to libeay32.a that is located in C:\OpenSSL-Win32\lib\MinGW\ (after installing OpenSSL).
In my case I am using CMake and the powerful CLion IDE, so I had to rename the library to libeay32.dll.a because CMake wasn't locating the library. This is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.1)
project(openssl_1_0_2a)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(C:\\OpenSSL-Win32\\include)
set(SOURCE_FILES main.cpp)
link_directories(C:\\OpenSSL-Win32\\lib\\MinGW)
add_executable(openssl_1_0_2a ${SOURCE_FILES})
target_link_libraries(openssl_1_0_2a eay32)
I made the test with this example (which is borrowed from this answer):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "openssl/aes.h"
int main(int argc, char* argv[])
{
AES_KEY aesKey_;
unsigned char userKey_[16];
unsigned char in_[16] = {0};
unsigned char out_[16] = {0};
strcpy((char *) userKey_,"0123456789123456");
strcpy((char *) in_,"0123456789123456");
fprintf(stdout,"Original message: %s\n", in_);
AES_set_encrypt_key(userKey_, 128, &aesKey_);
AES_encrypt(in_, out_, &aesKey_);
AES_set_decrypt_key(userKey_, 128, &aesKey_);
AES_decrypt(out_, in_,&aesKey_);
fprintf(stdout,"Recovered Original message: %s XXX \n", in_);
return 0;
}

I think the order of the parameter should be reset like follows:
gcc -I/home/aleksei/openSSL0.9.8/include -o app tema1.c -L . -lssl -lcrypto

Related

Attempting to link conio to my makefile. make returns cannot find -lconio

I'm writing my first makefile. I wanted to link 2 files together. test.c and main.c. test.c includes a test.h as well as a header file, conio.h.
So far I've tried adding the header file to the paths returned after the failing make command, as well as adding the path to the header file in the command itself. For reference I'm using git bash. To add the make command to git bash I needed to add it directly to the bin folder of gits mingw, but it is looking program files x86 / mingw, which also contains conio.h
Do I need to link it to some kind of library instead. Any help in the matter would be appreciated.
gcc main.o test.o -o test -lconio
C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lconio
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:7: main] Error 1
main.c
#include "test.h"
int main() {
char c = inputChar();
return 0;
}
test.c
#include "test.h"
#include <conio.h>
void printChar(char casd)
{
_putch(casd);
}
void printString(const char *c) {
for (const char* s = c; *s != 0; s++) {
printChar(*s);
}
printChar('\n');
}
char inputChar() {
char c = _getch();
printChar(c);
return c;
}
test.h
void printChar(char);
void printString(const char *c);
char inputChar();

How to fix 'undefined reference' when compiling in C?

I'm trying to compile a C program linking two previously created object files but keep getting an 'undefined reference' error.
I'm using Visual Code to write the code and Ubuntu on Windows to compile using a makefile. The two C files, task5.c and reverse.c which have been made into object files both contain #include reverse.h statements which contains the prototypes for the functions in reverse.c.
task5.c
#include <stdio.h>
#include "ctap.h"
#include "reverse.h"
TESTS {
const char *a = "Family";
char *b = reverse(a);
//test 1
ok(string_length(a) == string_length(b), "Strings are the same size");
//test 2
is("ylimaF", b, "Strings match");
}
reverse.c
#include <stdio.h>
#include <stdlib.h>
#include "reverse.h"
char *reverse(const char *str) {
//code
}
int string_length(const char *str) {
//code
}
reverse.h
char *reverse(const char *str);
int string_length(const char *str);
makefile
linked:
gcc -o linked task5.o reverse.o
task5.o
gcc -c -o task5.o task5.c
reverse.o
gcc -c -o reverse.o reverse.c
When I run the command make linked I expect it to be made and return nothing.
But when I run that command I get this error:
cc task5.o -o linked
task5.o: In function `ctap_tests':
task5.c:(.text+0x1abe): undefined reference to `reverse'
task5.c:(.text+0x1ace): undefined reference to `string_length'
task5.c:(.text+0x1adc): undefined reference to `string_length'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'linked' failed
make: *** [task5] Error 1
According to this GNU make documentation, the GNU make program will try to use GNUMakefile, makefile or Makefile.
The make program will not try makefile.mk, which means that e.g. make linked will use no makefile and only the default rules.
You can solve this by either renaming your makefile as Makefile (the most common) or makefile; Or by using the -f option to specify the makefile
$ make -f makefile.mk linked

Only link certain symbols from a library

I am developing an embedded system with GCC, and would like to only use a few symbols from libc. For instance, I would like to use the basic memcpy, memmove, memset, strlen, strcpy, etc. However, I would like to provide my own (smaller) printf function, so I do not want libc to privide printf. I don't want dynamic allocation in this platform, so I do not want malloc to resolve at all.
Is there a way to tell GCC "only provide these symbols" from libc?
edit: To be clear, I am asking if there is a way I can only provide a few specific symbols from a library, not just override a library function with my own implementation. If the code uses a symbol that is in the library but not specified, the linker should fail with "unresolved symbol". If another question explains how to do this, I haven't yet seen it.
This should happen "automatically" as long as your libc and linker setup supports it. You haven't told what your platform is, so here is one where it does work.
So, let's create a silly example using snprintf.
/*
* main.c
*/
#include <stdio.h>
int main(int argc, char **argv) {
char l[100];
snprintf(l, 100, "%s %d\n", argv[0], argc);
return 0;
}
try to compile and link it
$ CC=/opt/gcc-arm-none-eabi-4_7-2013q3/bin/arm-none-eabi-gcc
$ CFLAGS="-mcpu=arm926ej-s -Wall -Wextra -O6"
$ LDFLAGS="-nostartfiles -L. -Wl,--gc-sections,-emain"
$ $CC $CFLAGS -c main.c -o main.o
$ $CC $LDFLAGS main.o -o example
/opt/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
It needs _sbrk because newlib *printf functions use malloc which needs a way to allocate system memory. Let's provide it a dummy one.
/*
* sbrk.c
*/
#include <stdint.h>
#include <unistd.h>
void *_sbrk(intptr_t increment) {
return 0;
}
and compile it
$ $CC $CFLAGS -c sbrk.c -o sbrk.o
$ $CC $LDFLAGS -Wl,-Map,"sbrk.map" main.o sbrk.o -o with-sbrk
$ /opt/gcc-arm-none-eabi-4_7-2013q3/bin/arm-none-eabi-size with-sbrk
text data bss dec hex filename
28956 2164 56 31176 79c8 with-sbrk
Well, that's the reason you'd like to get rid of printf and friends, isn't it? Now, replace snprintf with our function
/*
* replace.c
*/
#include <stdio.h>
#include <string.h>
int snprintf(char *str, size_t size, const char *format, ...) {
return strlen(format);
}
then compile
$ $CC $CFLAGS -c replace.c -o replace.o
$ $CC $LDFLAGS -Wl,-Map,"replace.map" main.o replace.o -o with-replace
$ /opt/gcc-arm-none-eabi-4_7-2013q3/bin/arm-none-eabi-size with-sbrk
text data bss dec hex filename
180 0 0 180 b4 with-replace
Note that we did not use the _sbrk stub at all. As long as you don't provide _sbrk, you can be sure that malloc is not (can't be) linked and used.
The simplest solution is probably to use a wrapper which defines the symbols and resolves them at runtime using dlfcn:
#include <dlfcn.h>
void* (*memcpy)(void *dest, const void *src, size_t n);
char* (*strncpy)(char *dest, const char *src, size_t n);
...
void init_symbols (void) {
void *handle = dlopen("/lib/libc.so.6", RTLD_LAZY);
memcpy = dlsym(handle, "memcpy");
strncpy = dlsym(handle, "strncpy");
...
}
and link your binary with -nostdlib. This gives you the best control on which symbols to use from which source.

Libelf : Undefined Reference for functions

I am trying to use Libelf library to get some info on some elf files. But I keep getting these "undefined reference to [...]". I installed the libelf from the synaptic (tried to get from website too), and the lib seems to be instaled okay.
My code :
#include <err.h>
#include <fcntl.h>
#include <sysexits.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <libelf.h>
int main(int argc, char * argv[]) {
Elf *elf_file;
Elf_Kind elf_kind_file;
int file_descriptor;
if((argc!=2))
printf("Argumento em formato nao esperado\n");
file_descriptor = open(argv[1], O_RDONLY, 0);
elf_file = elf_begin(file_descriptor, ELF_C_READ, NULL);
elf_kind_file = elf_kind(elf_file);
elf_end(elf_file);
close(file_descriptor);
return 0;
}
Here is what I get from the terminal (Currently using Ubuntu 11.4):
gcc sample.c -o sample
/tmp/ccP7v2DT.o: In function `main':
sample.c:(.text+0x57): undefined reference to `elf_begin'
sample.c:(.text+0x67): undefined reference to `elf_kind'
sample.c:(.text+0x77): undefined reference to `elf_end'
collect2: ld returned 1 exit status
UPDATE
Solved all but one of my problems putting -lelf before my file during the compiling. The last one I could only solve updating my libelf to a new version (that wasn't available on the Synaptic Manager):
wget http://ftp.br.debian.org/debian/pool/main/e/elfutils/libelf-dev_0.153-1_i386.deb
wget http://ftp.br.debian.org/debian/pool/main/e/elfutils/libelf1_0.153-1_i386.deb
sudo dpkg -i libelf-dev_0.153-1_i386.deb libelf1_0.153-1_i386.deb
You probably need to link to the library. The standard way to do this is:
gcc sample.c -l elf -o sample
This searches the standard library directories for libelf.a, and includes the relevant object files in that archive into the build. Assuming the library has been installed correctly, libelf.a or a similarly-named file should exist.

C Undefined reference

I have the following code:
main.c
#include "checksum.h"
void main()
{
char *Buf ="GPGGA204502.005106.9813N11402.2921W1090.91065.02M-16.27M";
checksum(Buf);
}
checksum.c
#include <stdio.h>
#include <string.h>
checksum(char *Buff)
{
int i;
unsigned char XOR;
unsigned long iLen = strlen(Buff);
printf("Calculating checksum...\n");
for (XOR = 0, i = 0; i < iLen; i++)
XOR ^= (unsigned char)Buff[i];
printf("%X \n",XOR);
}
checksum.h
#ifndef CHECKSUM_H_INCLUDED
#define CHECKSUM_H_INCLUDED
void checksum(char *Buff);
#endif
When compiling I get the following error:
/tmp/ccFQS7Ih.o: In function `main':
main.c:(.text+0x18): undefined reference to `checksum'
collect2: ld returned 1 exit status
I can't figure out what the problem is?
You are compiling only one file not both. More precisely, you are not linking the files together.
I don't know your compiler, but with gcc, it would be something like this:
gcc -c main.c <-- compile only
gcc -c checksum.c <-- compile only
gcc main.o checksum.o <-- link the two
Edit: To automate this process, take a look at the make program which reads Makefiles.
You could also try
gcc -o program.out main.c checksum.c which will compile and link both files together
I think: in checksum.c, you should include checksum.h.

Resources