Unable to compile a c application that reads smartcard - c

I am trying to compile an example c application that is using pkcs#11 to finds all
the private keys on the token, and print their label and id, but getting following errors
/tmp/ccAqQ7UI.o: In function initialize':
pkcs11_example1.c:(.text+0x8e5): undefined reference to C_Initialize'
/tmp/ccAqQ7UI.o: In function `get_slot':
The example is taken from here
compilling by using following command;
`gcc pkcs11_example1.c -o slots -L /usr/lib/opensc-pkcs11.so`
I am not sure which library i should link after -L.
Can anyone guide how to compile this and are there some libraries required to link.

C_Initialize and other 60+ functions with "C_" prefix are cryptoki functions defined in PKCS#11 specification. They are usually implemented in standalone library provided by HSM vendor. Looking at your code samples I would say that you need to directly link also PKCS#11 library or you can modify the code to dynamically load PKCS#11 library in runtime with LoadLibrary or dlopen and then acquire pointers to all cryptoki functions via the C_GetFunctionList call. You can also take a look at pkcs11-logger the source code for an example on how to do that.

The link command you give, gcc pkcs11_example1.c -o slots -L /usr/lib/opensc-pkcs11.so, is wrong.
-L takes just path, which is added to paths where libs are searched from, but /usr/lib is default so you don't need this switch at all.
You are missing -l, which takes the library name without lib prefix or .so suffix, so looks like you need -lopensc-pkcs11.
So, first make sure your library file really is /usr/lib/libopensc-pkcs11.so (note lib prefix!) possibly with verion numbers following. Then change build options so link command becomes
gcc pkcs11_example1.c -o slots -lopensc-pkcs11

Related

How to link an externally built C library to Ada default runtime math services (sin, cos, etc.)?

I need to use an externally built C library doing some calculation with trigonometric services to my Ada program. I do it well using an stm32 bb runtime (SFP) but when trying to do the same in a native environment using the default Ada runtime, I end up with linking problems. Hope I can find some help here.
I tried several configurations of project files (gpr) solutions and I always end up with the same kind of linking error:
Memory region Used Size Region Size %age Used/opt/gnat/gnat_native/bin/../libexec/gcc/x86_64-pc-linux-gnu/7.3.1/ld: /home/pulsar/repos/pulsar-software/something/lib_c/libC.a(something.o): in function `compute':
(.text+0xa5): undefined reference to `sin'
collect2: error: ld returned 1 exit status
Here is what I've got so far.
The C library build sequence is as follows (confirmed by the library provider):
$ gcc -c something.c -o something.o
$ ar -r libsomethingLib.a something.o
The C library gpr file something_lib_c.gpr:
library project Something_Lib_C is
for Languages use ("C");
for Externally_Built use "true";
for Source_Dirs use ("src_c");
for Library_Dir use "lib_c";
for Library_Name use "somethingLib";
for Library_Kind use "static";
end Geocaging_Lib_C;
In the lib_c directory, I have the actual library libsomethingLib.a
In the src_c directory, I have the header API to use the C library (something.h):
#ifndef _GEOCAGING_H
#define _GEOCAGING_H
typedef struct something_s something_t;
extern void compute(something_t* const self);
#endif // _GEOCAGING_H
Then here is the Ada project file that wraps the C library something_lib.gpr:
with "something_lib_c.gpr";
project Something_Lib extends "../settings.gpr" is
for Languages use ("Ada");
for Source_Dirs use ("./src_ada");
for Object_Dir use "obj" & "/" & Target & "/" & Build;
end Geocaging_Lib;
In the directory src_ada, I have the Ada API wrapper (something_api.ads):
with Interfaces; use Interfaces;
with Interfaces.C; use Interfaces.C;
package Something_API is
type T_Something is null record;
procedure Compute (Something : access T_Something);
with Import => True,
Convention => C,
External_Name => "compute";
end Something_API;
And finally, I call the compute service from my Ada program by with-ing the Ada API wrapper.
Once again, when building/linking the whole thing for an arm-eabi target, using an stm32-full or stm32-sfp Ada runtime, everything runs well and the behavior of the library is validated.
The whole point is I'd like to do the thing in a native environment in order to run CI tests on it and I can't find a way to pass the link stage.
Last thing, in the Settings.gpr generic project file contains some common Ada build/bind/build switches that I can provide if necessary. But I can't see how this could work in arm and not in native with the same options. This HAS to be linked to the default Ada runtime thing...
Any idea?
If you were building with a C main program, what would you have to do to bring in the maths libraries at link time? ... possibly something like
gcc foo.c -l somethingLib -lm
What you need to do is to arrange for the -lm to be included whenever you call in something_lib_c.gpr.
I think that what you need to do is to modify library project Something_Lib_C to include the line
for Library_Options use ("-lm");
OK, my HUGE apologies to all of you who tried to help...
The solution was more obvious than I thought, I was just too obsessed with the thing working in arm and not in native.
BUT, the solution was simply to add the -lm switch to the global linker switches. Hence:
Ada_Switches_Linker_Native := (
"-Wl,--gc-sections"
,"-Wl,--verbose"
,"-Wl,-lm"
);
package Linker is
case Target is
when "native" =>
for Switches ("Ada") use Ada_Switches_Linker_Native;
...
end case;
end Linker;
In case it could be of interest for someone else, the fact that it works straightforward in arm environment and not in native is because the default runtime does not embed a specific mathematical library and you are supposed to use the C one provided by gcc, linking through the -lm switch.
In the contrary, when using a target specific runtime like arm (for stm32f4 for example), the correct mathematical libraries are provided, selected and automatically linked depending on your compilation options (-mhard-float, -msoft-float, etc.).
Sorry again and thank you very much for your time.

Linking shared libraries with gcc on Linux

I need to compile and, most importantly, link a C program that uses a proprietary function present in a shared library file. Because of lack of communication with the previous development team, there is no proper documentation. I declared a function prototype (because I know the number and type of arguments):
int CustomFunction(unsigned char *in, int size);
Since that function name can be grepped from /customlibs/libcustom.so, I tried to compile the code and link it like this:
gcc -L/customlibs testing.c -o testing -lcustom
Which throws a few error messages looking like this:
/customlibs/libcustom.so: undefined reference to `AnotherCustomFunction'
Obviously, I need to tell linker to include other libraries as well, and, to make things worse, they need to be in certain order. I tried exporting LD_LIBRARY_PATH, using -Wl,-rpath=, -Wl,--no-undefined and -Wl,--start-group. Is there an easy way to give the linker all the .so files without the proper order?
I found the solution (or a workaround) to my problem: adding -Wl,--warn-unresolved-symbols, which turns errors to warnings. Note that this works only if you are ABSOLUTELY certain your function does not depend on the symbols mentioned in undefined refernce to: messages.
Add them on the command line is a way to do it. Something like this below. The LD_LIBRARY_PATH tells gcc where to look for libraries, but you still need to say what libraries to include.
gcc -L/customlibs testing.c -o testing -lcustom -lmylib1 -lmylib2 -lmylib3
You should also include all the header files of your shared library by adding the -I option of gcc, for example : gcc [...] -I/path/to/your/lib/header/files [...]

Statically linking libclang in C code

I'm trying to write a simple syntax checker for C code using the frontend available in libclang. Due to deployment concerns, I need to be able to statically link all the libraries in libclang, and not pass around the .so file that has all the libraries.
I'm building clang/llvm from source, and in llvm/Release+Asserts/lib I have a bunch of .a files that I think I should be able to use, but it never seems to work (the linker spews out thousands of errors about missing symbols). However, when I compile it using the libclang.so also present in that directory as follows:
clang main.c -o bin/dlc -I../llvm/tools/clang/include -L../llvm/Release+Asserts/lib/ -lclang
Everything seems to work well.
What is the minimum set of .a files I need to include to make this work? I've tried including absolutely all of the .a files in the build output directory, with them provided to clang/gcc in different orders, without any success. I only need the functions mentioned in libclang's Index.h, but there don't seem to be any resources or documentation on what the various libclang*.a files are for. It would be very helpful to know which files libclang.so pulls in.
The following is supposed to work, as long the whole project has all static libraries (I counted 116 in my Release/lib directory).
clang main.c -o bin/dlc -I../llvm/tools/clang/include ../llvm/Release/lib/*.a
[edit: clang main.c -o bin/dlc -I../llvm/tools/clang/include ../llvm/Release/lib/libclang.a ../llvm/Release/lib/*.a]
Note that the output binary is not static, so you don't need any -static flag for gcc or ld, if you're using this syntax.
If that doesn't work you might need to list the libraries in order: if some library requires a function available in another library, then it may be necessary to list it first in the command line. See comments about link order at:
http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Link-Options.html#Link-Options

Is there a way to load user library's from specific location ONLY on running the binary

I have a shared library's libmyworld.so in /opt/my_prog/lib and also in /home/user1/lib
Irrespective of the order I specified in LD_LIBRARY_PATH (LD_LIBRARY_PATH=/home/user1/lib;/opt/myprog/lib); my binary SHOULD always look for libmyworld.so FIRST in /opt/my_prog/lib;
Can this be done using GCC during compilation time? without modifying my_prog binary. Thanks in advance.
The search order for dynamic libraries in Linux (from ld.so man page) is the following
Using the DT_RPATH dynamic section attribute of the binary
if present and DT_RUNPATH attribute does not exist. Use of
DT_RPATH is deprecated.
Using the environment variable LD_LIBRARY_PATH. Except if
the executable is a setuid/setgid binary, in which case it
is ignored.
Using the DT_RUNPATH dynamic section attribute of the binary
if present.
From the cache file /etc/ld.so.cache which contains a
compiled list of candidate libraries previously found in the
augmented library path. If, however, the binary was linked
with -z nodeflib linker option, libraries in the default
library paths are skipped.
In the default path /lib, and then /usr/lib. If the binary
was linked with -z nodeflib linker option, this step is
skipped.
When linking, to set
DT_RUNPATH: use -Wl,--enable-new-dtags -Wl,-R$(RUNPATH)
DT_RPATH: use -Wl,--disable-new-dtags -Wl,-R$(RPATH)
In theory, it is better to use DT_RUNPATH as the LD_LIBRARY_PATH, on which the user has a control, has precedence. But here you want to avoid the user control, so use the DT_RPATH. In you link line:
-Wl,--disable-new-dtags -Wl,-R/opt/my_prog/lib
You can always launch your binary (here called foo) with
$ LD_LIBRARY_PATH=/opt/my_prog/lib foo
or make a shell script with the line above.
While compiling your source code use the below command
gcc -o [desired_executable_file_name] -L [Your shared library path] -l [your shared library name] -I [Header file path]
for example in your case
gcc -o my_word_exe -L /opt/my_prog/lib -lmyworld -I [header path if their]
Then it"ll take libmyworld.so in /opt/my_prog/lib this path
Use LD_PRELOAD.
LD_PRELOAD=/home/lib/libmyworld.so mybinary
The advantage is that you don't fiddle with LD_LIBRARY_PATH - your binary may depend on other shared libraries and it may need proper LD_LIBRARY_PATH/ld.so.conf/whatever.
PS. This is the least invasive and flexible solution, because does not affect loading of other libraries and does not hardcode paths in the user executable.

How to force use of static library over shared?

In my SConscript I have the following line:
Program("xtest", Split("main.cpp"), LIBS="mylib fltk Xft Xinerama Xext X11 m")
How do I get scons to use mylib.a instead of mylib.so, while linking dynamically with the other libraries?
EDIT: Looking to use as few platform specific hacks as possible.
Passing the full filepath wrapped in a File node will force static linking. For example:
lib = File('/usr/lib/libfoo.a')
Program('bar', 'main.c', LIBS = [lib])
Will produce the following linker command line
g++ -o bar main.o /usr/lib/libfoo.a
Notice how the "-l" flag is not passed to the linker for this LIBS entry. This effectively forces static linking. The alternative is to modify LINKFLAGS to get what you want with the caveat that you are bypassing the library dependency scanner -- the status of the library will not be checked for rebuilds.
To make this platform independent you append the env['SHLIBSUFFIX'] onto the library you want to use. env['SHLIBSUFFIX'] gives you this environments suffix for shared libraries.
You also have the ['SHLIBPREFIX'], ['LIBPREFIX'], ['LIBSUFFIX'] and ['PROGSUFFIX'], all useful for situations like this.
Edit:
I obviously haven't made myself understood, so I will clarify.
The return value of these lookups are strings to the pre/suffixes that platform uses. In that way you can refer to the file you need on each platform. Note that you cannot use it as a pure string, it has to be embedded as a file node as BennyG suggests. Working with nodes are anyway the best solution as file nodes are much more versatile than a string.
Hope this helps.

Resources