How to parse openssl config file from C++ code? - c++

I have a question regarding openssl. I am looking for some examples where we can access/retrieve the name=value pair from the openssl.cnf file. For example I have below openssl.cnf file:
.
.
[engine_section]
pkcs11 = pkcs11_section
[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/lib/engines-1.1/pkcs11.so
MODULE_PATH = /usr/lib/libtpm2_pkcs11.so
PIN = 12xx
default_algorithms = ALL
init = 0
Now, if I want to access PIN value within the C++ source code, how can this be achieved? Does openssl has any parsing tool for such cases? Any alternative way to do this is also helpful.
The official doc of openssl config file mentions
The OpenSSL CONF library can be used to read configuration files.
But I could not find any examples of using this library.
Thanks in advance.
P.S: Please let me know if further info is needed

Related

Compiling OpenSSL in Windows - generated LIB uses wrong name for DLL files

I'm trying to compile OpenSSL 1.1.1d version locally.
Due to my project, I need to edit windows-makefile.tmp under Configuration folder.
I have to prepend the file extensions like so:
our $objext = $target{obj_extension} || "_vc10.obj";
our $resext = $target{res_extension} || "_vc10.res";
our $depext = $target{dep_extension} || "_vc10.d";
our $exeext = $target{exe_extension} || "_vc10.exe";
our $libext = $target{lib_extension} || "_vc10.lib";
our $shlibext = $target{shared_extension} || "_vc10.dll";
Compilation is finished successfully, no problems.
But I had errors whenever my program uses libcrypto.
Upon inspection of the generated libcrypto-1_1_vc10.lib, I found out that the lib uses .dll with name
libcrypto-1_1.dll
instead of the prepended
libcrypto-1_1_vc10.dll
I expected the latter will be used since, well, this will be the generated .dll file.
I also tried to prepend the following file extensions, but it didn't do much.
our $shlibextimport = $target{shared_import_extension} || ".lib";
our $dsoext = $target{dso_extension} || ".dll";
I skimmed through the generated Makefile but I don't see much that will generated only libcrypto-1_1.dll (Or probably I'm not yet familiar on how Makefile works).
Due to my project, I need to keep the _vc10 on the file names.
Are there other parts of the windows-makefile.tmp or other configuration that I need to edit?
Any clues will be beneficial. Thank you in advance.
After some investigation and thanks to the notes of my colleagues, I was able to resolve this issue.
This maybe a hackish way to resolve this but this is how I fixed my issue.
In
util/mkdef.pl
there is a function
sub print_def_file
{
...
my $libname = $name;
...
Update the $libname value to your desired libname referenced by libcrypto.lib or libssl.lib
ex:
my $libname = $name . "_vc10";
PS: If there are other ways to resolve this, please let me know.

C++ - I need a macro or an environment variable to detect when I am doing bazel run on Windows

As a workaround, I have to append "../../../../../../"s to the file paths I want to open that are part of my data dependencies when I run my executable using bazel on Windows. See also the comment linked here: C++ Bazel project with a Data repository
I would like to have something like this below, which would simplify my application testing a lot:
auto basePath = "dataDir/subDir/"s;
if( isRunningFromBazelOnWindows() ) basePath = "../../../../../../"s + basePath;
auto file = std::ifstream{basePath + "dataFile"};
...
how can I code isRunningFromBazelOnWindows()?
Thanks!
Bazel now (maybe not yet released in stable bazel?) provides runfiles libraries simplifying access to runfiles. I guess the design doc is best place to start.

Open a downloadable file

I use open_in to open a local file with its path:
let f = open_in "/Users/SoftTimur/file.txt" in
...
Now, I would like to open a downloadable file with its URL:
let f = open_in "http://caml.inria.fr/distrib/ocaml-4.02/ocaml-4.02-refman.txt" in
...
returns an error Fatal error: exception Sys_error("http://caml.inria.fr/distrib/ocaml-4.02/ocaml-4.02-refman.txt: No such file or directory").
Does anyone know which function I could use to open such a downloadable file? Do I have to first download it to local (how to do that by OCaml?)?
Well, there are plenty of libraries in OCaml that can deal with http protocol in particular and with network communications in general. None of them will provide a function of type string -> in_channel as the in_channel type is an abstraction owned by OCaml. The language doesn't allow us to create our own implementations of the channel type1.
The libraries, that I know and used are:
cohttp - asynchronous library for http client and servers;
ocurl - a binding to the libcurl;
ocamlnet - all things network and even much more;
Presumably there are others, please feel free to edit this answer and add them.
I personally prefer asynchronous monadic cohttp, but it is easier to start with ocamlnet, that is also an excellent library, that has lots of features. This is how to play with it in the OCaml toplevel:
# #use "topfind"
# #require "netclient";
# module Client = Nethttp_client.Convenience
# let ocamldoc = Client.http_get "http://caml.inria.fr/distrib/ocaml-4.02/ocaml-4.02-refman.txt";;
Before starting the playing, make sure that you installed it with
opam install ocamlnet
Footnotes:
at least in pure OCaml, it is possible to create it from C, but I doubt if someone will pursue in this direction, it doesn't worth.
In Ocaml this is an C fopen call, no way to do it with a http source scheme.
You will have to download the file first, use one of the usual download tools wget or curl which are used in your linux package manager as well. Sys.command is your friend to do this.
It would be not too hard writing a module that checks the file name for a "schema:" like prefix, and taking appropriate action.
Maybe look at the opam sources for inspiration?
Does anyone know which function I could use to open such a downloadable file?
Install the wget program for your Linux distro and use the Unix library when you compile and you can use:
let open_url_in = Unix.open_process_in("wget -O - " ^ url)
This runs the wget program with -O o asking it to output the downloaded file to stdout which open_process_in reads into your process as the resulting channel.
Do I have to first download it to local (how to do that by OCaml?)?
No.

How do I set up scons to build a project that has generated source files?

I'm working on a C++ project that has some hand coded source files, as well as some source and header files that are generated by a command line tool.
The actual source and header files generated are determined by the contents of a JSON file that the tool reads, and so cannot be hardcoded into the scons script.
I would like to set up scons so that if I clean the project, then make it, it will know to run the command line tool to generate the generated source and header files as the first step, and then after that compile both my hand coded files and the generated source files and link them to make my binary.
Is this possible? I'm at a loss as to how to achieve this, so any help would be much appreciated.
Yes, this is possible. Depending on which tool you're using to create the header/source files, you want to check our ToolIndex at https://bitbucket.org/scons/scons/wiki/ToolsIndex , or read our guide https://bitbucket.org/scons/scons/wiki/ToolsForFools for writing your own Builder.
Based on your description you'll probably have to write your own Emitter, which parses the JSON input file and returns the filenames that will finally result from the call. Then, all you need to do is:
# creates foo.h/cpp and bar.h/cpp
env.YourBuilder('input.json')
env.Program(Glob('*.cpp'))
The Glob will find the created files, even if they don't physically exist on the hard drive yet, and add them to the overall dependencies.
If you have further questions or problems arise, please consider subscribing to our User mailing list at scons-users#scons.org (see also http://scons.org/lists.html ).
Thanks to Dirk Baechle I got this working - for anyone else interested here is the code I used.
import subprocess
env = Environment( MSVC_USE_SCRIPT = "c:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\bin\\vcvars32.bat")
def modify_targets(target, source, env):
#Call the code generator to generate the list of file names that will be generated.
subprocess.call(["d:/nk/temp/sconstest/codegenerator/CodeGenerator.exe", "-filelist"])
#Read the file name list and add a target for each file.
with open("GeneratedFileList.txt") as f:
content = f.readlines()
content = [x.strip('\n') for x in content]
for newTarget in content:
target.append(newTarget)
return target, source
bld = Builder(action = 'd:/nk/temp/sconstest/codegenerator/CodeGenerator.exe', emitter = modify_targets)
env.Append(BUILDERS = {'GenerateCode' : bld})
env.GenerateCode('input.txt')
# Main.exe depends on all the CPP files in the folder. Note that this
# will include the generated files, even though they may not currently
# exist in the folder.
env.Program('main.exe', Glob('*.cpp'))
There's an example at:
https://github.com/SCons/scons/wiki/UsingCodeGenerators
I'll also echo Dirk's suggestion to join the users mailing list.

Create a zip archive in c++

Is there a way to create a zip archive with the full folder content or multi-files.
I actually looked the example on the web but each time it's a compression of file only based on a buffer like for example : gzip_compressor() or gzwrite()
I can't give a full path in input but only a file buffer.
=> Then no folder compression nor multi-file compression ???
Please note that I would like to use zlib/gzip or boost (the only library i can link)
I think I missed something there...
Can you please help me ?
Marc.
There are several libraries out there to handle zip files. They use zlib for the compression, decompression, and crc32 operations. You should look at libzip and DotNetZip.
It looks like this will work. If you are on a Unix environment you may have to run the Java version:
http://www.7-zip.org/sdk.html