How to check if openssl or cryptopp is installed and use the library that actually exists in the system (is installed)? - c

I wrote function that encrypts/decrypts a buffer (2 versions of the same function - first, with cryptopp, second - with openssl).
I would like to make something like this:
#if defined OPENSSL
run_aes_openssl(...);
#elif defined CRYPTOPP
run_aes_crytopp(...);
#else
error(...);
#end
Is it possible?

It's not quite that simple. In order to find that a macro is defined, you have to include the header that defines that macro. And C doesn't have anything like "include foo.h iff it exists"; it has to exist otherwise there is a compilation error.
Normally this would be sorted out by a script that you run before compilation. Your script checks locations like /usr/include, /usr/local/include, etc., to see if the OpenSSL headers are there; and then it outputs a Makefile which contains in the CFLAGS -DHAVE_OPENSSL. Then your code can check for that macro.
This is quite a bit of hullabaloo, to keep things simple you could require the user to manually edit a file , e.g. distribute your project with something called user_config.h that the user is supposed to edit before compiling, to specify where they put OpenSSL and so on.
There is a preset system called GNU Autoconf which contains a script that checks your system for everything under the sun. This has its advantages and disadvantages; it makes things easier for plebs downloading your source code, but it is bloaty and can be hard work for yourself.

How to check if openssl or cryptopp is installed and use the library that actually exists in the system (is installed)?
If your application was built on the system it is running, then the code you have shown is OK. Presumably, the build system will detect both OpenSSL and Crypto++. In the case both are available, it looks like your code will favor OpenSSL.
If you application is built elsewhere and needs to check at runtime, then you will need dlopen, dlsym, dlclose and friends.
In the case of runtime checking, its probably best to build a dispatch table and call through it. For example, you might have a table with function pointers to your internal run_aes_openssl, run_aes_crytopp, etc.
Upon startup, you populate the table based on the results of dlopen. If you find OpenSSL, then you populate your table with the OpenSSL gear. If you find Crypto++, then you populate your table with the Crypto++ gear.
C++ can be painful to use with dlopen and friends because of name mangling. Worse, the mangling differs between distributions and runtime library versions. For example, here's a function to generate a private RSA key:
RSA::PrivateKey key;
key.GenerateRandomWithKeySize(prng, 1024);
And here's the corresponding function names on Mac OS X. Debian and Red Hat will likely be different.
$ nm cryptopp-test.exe | grep -i GenerateRandom | grep -i RSA
00000001000c7d80 T __ZN8CryptoPP21InvertibleRSAFunction14GenerateRandomERNS_21RandomNumberGeneratorERKNS_14NameValuePairsE
00000001000c8eb0 T __ZThn120_N8CryptoPP21InvertibleRSAFunction14GenerateRandomERNS_21RandomNumberGeneratorERKNS_14NameValuePairsE

Related

M1 mac using clion with cmake and homebrew to use sdl2_gfx error [duplicate]

Looking around on the net I have seen a lot of code like this:
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
target_include_directories(app SYSTEM PUBLIC ${SDL2_INCLUDE_DIRS})
target_link_libraries(app ${SDL2_LIBRARIES})
However that seems to be the wrong way about doing it, as it only uses the include directories and libraries, but ignored defines, library paths and other flags that might be returned by pkg-config.
What would be the correct way to do this and ensure that all compile and link flags returned by pkg-config are used by the compiled app? And is there a single command to accomplish this, i.e. something like target_use(app SDL2)?
ref:
include()
FindPkgConfig
First of, the call:
include(FindPkgConfig)
should be replaced with:
find_package(PkgConfig)
The find_package() call is more flexible and allows options such as REQUIRED, that do things automatically that one would have to do manually with include().
Secondly, manually calling pkg-config should be avoid when possible. CMake comes with a rich set of package definitions, found in Linux under /usr/share/cmake-3.0/Modules/Find*cmake. These provide more options and choice for the user than a raw call to pkg_search_module().
As for the mentioned hypothetical target_use() command, CMake already has that built-in in a way with PUBLIC|PRIVATE|INTERFACE. A call like target_include_directories(mytarget PUBLIC ...) will cause the include directories to be automatically used in every target that uses mytarget, e.g. target_link_libraries(myapp mytarget). However this mechanism seems to be only for libraries created within the CMakeLists.txt file and does not work for libraries acquired with pkg_search_module(). The call add_library(bar SHARED IMPORTED) might be used for that, but I haven't yet looked into that.
As for the main question, this here works in most cases:
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
...
target_link_libraries(testapp ${SDL2_LIBRARIES})
target_include_directories(testapp PUBLIC ${SDL2_INCLUDE_DIRS})
target_compile_options(testapp PUBLIC ${SDL2_CFLAGS_OTHER})
The SDL2_CFLAGS_OTHER contains defines and other flags necessary for a successful compile. The flags SDL2_LIBRARY_DIRS and SDL2_LDFLAGS_OTHER are however still ignored, no idea how often that would become a problem.
More documentation here http://www.cmake.org/cmake/help/latest/module/FindPkgConfig.html
If you're using cmake and pkg-config in a pretty normal way, this solution works.
If, however, you have a library that exists in some development directory (such as /home/me/hack/lib), then using other methods seen here fail to configure the linker paths. Libraries that are not found under the typical install locations would result in linker errors, like /usr/bin/ld: cannot find -lmy-hacking-library-1.0. This solution fixes the linker error for that case.
Another issue could be that the pkg-config files are not installed in the normal place, and the pkg-config paths for the project need to be added using the PKG_CONFIG_PATH environment variable while cmake is running (see other Stack Overflow questions regarding this). This solution also works well when you use the correct pkg-config path.
Using IMPORTED_TARGET is key to solving the issues above. This solution is an improvement on this earlier answer and boils down to this final version of a working CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project(ya-project C)
# the `pkg_check_modules` function is created with this call
find_package(PkgConfig REQUIRED)
# these calls create special `PkgConfig::<MODULE>` variables
pkg_check_modules(MY_PKG REQUIRED IMPORTED_TARGET any-package)
pkg_check_modules(YOUR_PKG REQUIRED IMPORTED_TARGET ya-package)
add_executable(program-name file.c ya.c)
target_link_libraries(program-name PUBLIC
PkgConfig::MY_PKG
PkgConfig::YOUR_PKG)
Note that target_link_libraries does more than change the linker commands. It also propagates other PUBLIC properties of specified targets like compiler flags, compiler defines, include paths, etc., so, use the PUBLIC keyword with caution.
It's rare that one would only need to link with SDL2. The currently popular answer uses pkg_search_module() which checks for given modules and uses the first working one.
It is more likely that you want to link with SDL2 and SDL2_Mixer and SDL2_TTF, etc... pkg_check_modules() checks for all the given modules.
# sdl2 linking variables
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2 SDL2_ttf SDL2_mixer SDL2_image)
# your app
file(GLOB SRC "my_app/*.c")
add_executable(my_app ${SRC})
target_link_libraries(my_app ${SDL2_LIBRARIES})
target_include_directories(my_app PUBLIC ${SDL2_INCLUDE_DIRS})
target_compile_options(my_app PUBLIC ${SDL2_CFLAGS_OTHER})
Disclaimer: I would have simply commented on Grumbel's self answer if I had enough street creds with stackoverflow.
Most of the available answers fail to configure the headers for the pkg-config library. After meditating on the Documentation for FindPkgConfig I came up with a solution that provides those also:
include(FindPkgConfig)
if(NOT PKG_CONFIG_FOUND)
message(FATAL_ERROR "pkg-config not found!" )
endif()
pkg_check_modules(<some-lib> REQUIRED IMPORTED_TARGET <some-lib>)
target_link_libraries(<my-target> PkgConfig::<some-lib>)
(Substitute your target in place of <my-target> and whatever library in place of <some-lib>, accordingly.)
The IMPORTED_TARGET option seems to be key and makes everything then available under the PkgConfig:: namespace. This was all that was required and also all that should be required.
There is no such command as target_use. But I know several projects that have written such a command for their internal use. But every project want to pass additional flags or defines, thus it does not make sense to have it in general CMake. Another reason not to have it are C++ templated libraries like Eigen, there is no library but you only have a bunch of include files.
The described way is often correct. It might differ for some libraries, then you'll have to add _LDFLAGS or _CFLAGS. One more reason for not having target_use. If it does not work for you, ask a new question specific about SDL2 or whatever library you want use.
If you are looking to add definitions from the library as well, the add_definitions instruction is there for that. Documentation can be found here, along with more ways to add compiler flags.
The following code snippet uses this instruction to add GTKGL to the project:
pkg_check_modules(GTKGL REQUIRED gtkglext-1.0)
include_directories(${GTKGL_INCLUDE_DIRS})
link_directories(${GTKGL_LIBRARY_DIRS})
add_definitions(${GTKGL_CFLAGS_OTHER})
set(LIBS ${LIBS} ${GTKGL_LIBRARIES})
target_link_libraries([insert name of program] ${LIBS})

Unable to compile a c application that reads smartcard

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

FIPS_mode_set() code not found in openssl package

I am new to openssl, and I downloaded openssl-fips-2.0.1 codes from openssl, however, I was not able to trace to the definition of FIPS_mode_set() as stated in the documentation and security policy. I did find, however, fips_set_mode() in fips.c, but they are not referring to the same, am I right?
Where is the definition?
Please advise me.
FIPS_mode_set() code not found in openssl package
You have to know how to ask...
openssl-1.0.1f$ grep -R FIPS_mode_set *
apps/openssl.c: if (!FIPS_mode_set(1)) {
CHANGES: *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying
crypto/cpt_err.c:{ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"},
crypto/evp/evp_cnf.c: if (!FIPS_mode() && !FIPS_mode_set(1))
crypto/crypto.h:int FIPS_mode_set(int r);
crypto/o_fips.c:int FIPS_mode_set(int r)
Binary file fips_premain_dso matches
ssl/ssltest.c: if(!FIPS_mode_set(1))
util/libeay.num:FIPS_mode_set 3253 EXIST::FUNCTION:
openssl-1.0.1f$
The declaration is in crypto/crypto.h and the definition is in crypto/o_fips.c. Here's from o_fips.c:
int FIPS_mode_set(int r)
{
OPENSSL_init();
#ifdef OPENSSL_FIPS
#ifndef FIPS_AUTH_USER_PASS
#define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password"
#endif
if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS))
return 0;
if (r)
RAND_set_rand_method(FIPS_rand_get_method());
else
RAND_set_rand_method(NULL);
return 1;
#else
if (r == 0)
return 1;
CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED);
return 0;
#endif
}
If you were looking for FIPS_mode_set to enter into "FIPS mode" with special setup or switch some algorithms, that does not happen at this step.
It happens earlier when linking. What happens under the hood is fipsld is you compiler, and it looks for an invocation of LD. If LD is not invoked, then fipsld just calls your regular compiler (probably /usr/bin/gcc). If it sees an invocation of LD, then it does three things.
First, it compiles fips_premin.c. Then it calls the real ld to perform the final link with all your object file and the fips_premain.o it produced. Finally, it calls incore to swap in the FIPS Object Module, calculate the signature over the relevant text and data (relevant means the FIPS code and data), and then embeds the signature in the executable.
The signature is generated with an HMAC, and the key is embedded in the executable. There's nothing special about it, and its constant across all executables throughout the world. Here's the key used: etaonrishdlcupfm.
If you are not taking special steps when build your executable, then you are probably missing some steps. Here are the steps to use fipsld and incore:
$ export CC=`find /usr/local -name fipsld`
$ echo $CC
/usr/local/ssl/fips-2.0/bin/fipsld
$ export FIPSLD_CC=`find /usr/bin -name gcc`
$ echo $FIPSLD_CC
/usr/bin/gcc
Now, do a standard config and make. Sometimes you have to do config, then adjust CC and FIPSLD_CC, and then run make because some config files choke on the arrangement. Sometimes you have to open a Makefile after config and change CC to /usr/local/ssl/fips-2.0/bin/fipsld. There's lots of ways to do it in an effort to work around particular packaging.
I downloaded openssl-fips-2.0.1 codes from openssl, however, I was not able to trace to the definition of FIPS_mode_set()
openssl-fips-NNN provides the FIPS validated cryptography if you build the FIPS Object Module according to the Security Policy. You can find the OpenSSL FIPS 1402- Security Policy at here.
If all you did was download and build openssl-fips-NNN, then you are probably not using FIPS validated cryptography. There's a procedure to follow, and that includes getting a "trusted" copy of the source code. You can download and verify a signature, but you need a FIPS validated signature checker, which creates a chicken-and-the-egg problem because you can't build it from sources. So the practical solution is to order the CD from the OpenSSL Foundation. Its bizarre, but its the truth. See, for example, the OpenSSL FIPS User Guide or the OpenSSL FIPS Security Policy, Appendix B, Controlled Distribution File Fingerprint.
Once you have the FIPS Object Module built and installed, you can build the FIPS Capable version of the library. The FIPS Capable OpenSSL will use the FIPS Object Module, if available. Think of it as a "pluggable" architecture.
The FIPS Capable version of the library is simply openssl-NNN, such as openssl-1.0.1e and openssl-1.0.1f. Its what you know and love.
You might also consider something like ctags as a source code browser to help you find things and jump around. See Exuberant Ctags on Sourceforge.
Please refer header file crypto.h. I am able to find its definition there at line 566 as follows:
int FIPS_mode_set(int r);
Documentation clearly mention that it is in header file <openssl/crypto.h>.
So, in your code, include openssl/crypto.h to include the definition of this function. If you face other problem, you can browse through questions of OpenSSL that may help you.
For linkage FIPS_mode_set() should be available from libcrypto (*.a for static linkage and *.so for run-time linkage).
libcrypto.a/.so comes with your distro's openssl's developer package, or as a result of bulding openssl-x.y.z yourself.
You find the sources for FIPS_mode_set() in the sources for openssl-x.y.z, in the file crypto/o_fips.c.

How to avoid library finding CMakeLists feature

I'm trying to adjust 3rd person code to my needs. This code is provided with CMake config files used to build and install it. There is possibility to choose one of libraries. And in code is often used #ifdef USE_FTD2XX directive. I saw that this is defined in CMamkeFiles.txt file like here:
option(USE_FTD2XX "Use FTDI libFTD2XX instead of free libftdi" ON)
if(USE_FTD2XX)
find_package(libFTD2XX)
endif(USE_FTD2XX)
if(LIBFTD2XX_FOUND)
include_directories(${LIBFTD2XX_INCLUDE_DIR})
add_definitions( -DUSE_FTD2XX )
else(LIBFTD2XX_FOUND)
set(LIBFTD2XX_LIBRARIES "")
endif(LIBFTD2XX_FOUND)
But if I simply use *.c and *.cpp files and I analyse and run it simply from IDE (Codeblocks), how could I set using this library in C++ code instead of in CMake? I'm also sure that I want use always this one so it can be fixed.
Should I simply #define USE_FTD2XX in main file?
You cannot simply #define USE_FTD2XX because you also need specific linker options for this to work (i.e. the library to link with). If the option is OFF in cmake, the specific link options won't be present in the Makefile and most likely you'll have linker errors.
So CMake takes care of everything automatically for you, but you need to re-generate your makefiles each time you want to toggle options on/off.
If only headers were involved and no library to link with (like some parts of the Boost framework), then yeah, defining USE_FTD2XX in your should be enough.

Using List.h in C files, Ubuntu10.10

I am running Ubuntu 10.10 on an IBM R51 machine. When I access list.h to read it(manually/humanly) I open /usr/src/linux-headers-2.6.35-22/include/linux .
But when coding a C program in terminal, I cant invoke any #include because it is not in the default /usr/include folders.
When I change the statement to reflect the path by typing #include "/usr/src/linux-headers-2.6.35-22/include/linux/list.h" it returns errors as list.h in turn calls other header files which are mentioned as located in "linux" folder
The header files are as you must be aware:
"linux/poison.h", "linux/prefetch.h" and "asm/system.h"
So if I have to copy each, I can but prefetch in turn calls other dependencies, which are not present in /usr/include directory. I hope you understand.
How can I solve this problem?
Are you sure these headers are really what you need ? The standard C headers should be under /usr/include
Anyhow you need to pass the header search path to the compiler via the '-I' flag.
Pass the path via -I
-I/usr/src/linux-headers-2.6.35-22/include/linux
Then in your C code
#include "list.h"
Link to GCC manual & preprocessor directives
The header files you are using are designed for internal use of the Linux kernel. They were not designed to be used by a userland program.
If you MUST use these headers (the Linux kernel list implementation is brilliant), copy the headers into your program source directory. Copy each file that is referenced, edit each one to remove whatever assumptions exist about being used in-kernel, and recurse until you're finished. I might suggest to make your own prefetch() macro that simply does nothing, rather than try to untangle <linux/prefetch.h>. Do the same for <linux/poison.h>, and untangle <linux/types> and <linux/stddef.h> (not too hard here :) as best you can.
And also be sure you license your project GPLv2 (and specifically GPLv2, the Linux kernel's COPYING file is quite strict that GPLv2 is the only license that applies; there is debate whether the GPL allows specifying only one version, but that is the license Linus chose ages ago, and the license that is valid on all files unless specified otherwise).
adding -I/usr/src/linux is a no-go, since unsanitized header files are not meant to be used from user programs
you could manually copy list.h to your own project and sanitize
or use a library that is specifically for userspace and provides the same functionality (since you already used libHX elsewhere, you might want to continue reading into the linked list chapter)

Resources