Use libp11 on Windows environment - windows

I want to install all I need to use libp11 and use libp11.
What is my environment and needs:
I work on Windows 10, 64 bits.
I add package with pacman linux command on my mingw32 terminal (msys64 version of 2022/09/04).
I work on a Qt Creator editor and I have a .pro file to configure my Qt project.
I want to develop a C++ module for my application which use libp11 to get the Yubikey bin number and decrypt file.
Why I use a mingw32 terminal and not the mingw64, because, for the moment, the project is always in develop in QT 4.8.
What I do:
I read the README file and follow the installation step of the INSTALL file (first I follow the MinGW / MSYS chapter, then I follow the MSYS2 chapter.)
I do much more, but I don't remember every thing and I go in many wrong ways.
My problems and questions
I try to follow the examples find in GitHub.
I help me with the site cpp.hotexemples.com to find the second parameter for the PKCS11_CTX_load function. I find the st_engine_ctx structure on this project.
The project file:
TEMPLATE = app
CONFIG += console c++17
CONFIG -= app_bundle
CONFIG += qt
LIBS += \
-lp11 \
-lssl \
-lcrypto
SOURCES += \
TestYubikey.cpp \
main.cpp
HEADERS += \
TestYubikey.h
The header file:
#ifndef TESTYUBIKEY_H
#define TESTYUBIKEY_H
#include <libp11.h>
#include <cstdio>
#include <cstring>
#include <openssl/err.h>
#include <openssl/crypto.h>
#include <openssl/objects.h>
#include <openssl/engine.h>
#include <openssl/ui.h>
/* Engine configuration */
/* The PIN used for login. Cache for the ctx_get_pin function.
* The memory for this PIN is always owned internally,
* and may be freed as necessary. Before freeing, the PIN
* must be whitened, to prevent security holes.
*/
struct st_engine_ctx
{
char *pin = nullptr;
size_t pin_length = 0;
int verbose = 0;
char *module = nullptr;
char *init_args = nullptr;
UI_METHOD *ui_method = nullptr;
void *callback_data = nullptr;
int force_login = 0;
/* Engine initialization mutex */
#if OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)
CRYPTO_RWLOCK *rwlock = nullptr;
#else
int rwlock;
#endif
/* Current operations */
PKCS11_CTX *pkcs11_ctx = nullptr;
PKCS11_SLOT *slot_list = nullptr;
unsigned int slot_count = 0;
};
class TestYubikey
{
public:
TestYubikey();
};
#endif // TESTYUBIKEY_H
The source file:
//libp11 is a wrapper library for PKCS#11 modules with OpenSSL interface
#include "TestYubikey.h"
#include <iostream>
TestYubikey::TestYubikey()
{
// Create a new libp11 context
PKCS11_CTX *ctx = PKCS11_CTX_new();
std::cout << "ctx = " << ctx << std::endl;
/* load pkcs #11 module */
int rc = PKCS11_CTX_load(ctx, "C:\\msys64\\mingw32\\lib\\engines-1_1\\pkcs11.dll"); //I test with "libpkcs11.dll" and "pkcs11.dll" too.
std::cout << "rc = " << rc << std::endl;
if (rc == -1)
{
std::cout << "Loading pkcs11 engine failed";
unsigned long error_code = ERR_get_error();
const char* error_detail = ERR_reason_error_string(error_code);
std::cout << " (" << error_code << ") : " << std::string(error_detail) << std::endl;
}
else
{
std::cout << "Loading pkcs11 engine worked !" << std::endl;
}
}
My output console show:
11:59:27: Starting C:/Users/jgomez/Documents/build-SandBox-Desktop_Qt_4_8_7_MinGW_32_bit-Release/release/SandBox.exe...
ctx = 0x2ca8f50
rc = -1
Loading pkcs11 engine failed (0) : terminate called after throwing an instance of 'std::logic_error'
what(): basic_string: construction from null is not valid
11:59:29: C:/Users/jgomez/Documents/build-SandBox-Desktop_Qt_4_8_7_MinGW_32_bit-Release/release/SandBox.exe exited with code 3
My problem:
rc = -1

Solution :
use the Dll called opensc-pkcs11.dll provided with OpenSC project and it should work.
( https://github.com/OpenSC/OpenSC , after installing , it should be found here by default C:\Program Files (x86)\OpenSC Project\OpenSC\pkcs11)
Explantation :
I have encountered the same problem, and after messing around with the files I figured out that this error due the PKCS11_CTX_Load function.
PKCS11_CTX_Load , tries to load the pkcs11.dll , and then tries getting the address of "c_get_function_list" from this dll, which fails since it doesn't have that function.

Related

GetUserPreferredUILanguages() never returns more than two languages

I'm trying to retrieve the complete list of the user's preferred languages from a C++/Qt application, as configured in the "Region & language" page in the user's preferences:
For that, I am trying with the WinAPI function GetUserPreferredUILanguages(), on an up-to-date Windows 10 Pro system.
However, the function always only returns the first entry (the main Windows display language), and "en-US". If English is configured as the main language, then only "en-US" is returned. E.g., if I have (German, French, English) configured, ["de-de", "en-US"] is returned, French is omitted. If I add more languages to the list, they are omitted as well.
I also looked at User Interface Language Management, but to no avail. GetSystemPreferredUILanguages() for example only returns "en-US". GetUILanguageFallbackList() returns ["de-de", "de", "en-US", "en"].
The code I use:
// calling GetUserPreferredUILanguages() twice, once to get number of
// languages and required buffer size, then to get the actual data
ULONG numberOfLanguages = 0;
DWORD bufferLength = 0;
const auto result1 = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME,
&numberOfLanguages,
nullptr,
&bufferLength);
// result1 is true, numberOfLanguages=2
QVector<wchar_t> languagesBuffer(static_cast<int>(bufferLength));
const auto result2 = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME,
&numberOfLanguages,
languagesBuffer.data(),
&bufferLength);
// result2 is true, languageBuffer contains "de-de", "en-US"
Is this not the right function to use, or am I misunderstanding something about the language configuration in Windows 10? How can I get the complete list of preferred languages? I see UWP API that might do the job, but if possible, I'd like to use C API, as it integrated more easily with the C++ codebase at hand. (unmanaged C++, that is)
GlobalizationPreferences.Languages is usable from unmanaged C++ because GlobalizationPreferences has DualApiPartitionAttribute.
Here is a C++/WinRT example of using GlobalizationPreferences.Languages:
#pragma once
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.System.UserProfile.h>
#include <iostream>
#pragma comment(lib, "windowsapp")
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::System::UserProfile;
int main()
{
winrt::init_apartment();
for (const auto& lang : GlobalizationPreferences::Languages()) {
std::wcout << lang.c_str() << std::endl;
}
}
And a WRL example for those who cannot migrate to C++ 17:
#include <roapi.h>
#include <wrl.h>
#include <Windows.System.UserProfile.h>
#include <iostream>
#include <stdint.h>
#pragma comment(lib, "runtimeobject.lib")
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::System::UserProfile;
int main()
{
RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize)) {
std::cerr << "RoInitialize failed" << std::endl;
return 1;
}
ComPtr<IGlobalizationPreferencesStatics> gps;
HRESULT hr = RoGetActivationFactory(
HStringReference(
RuntimeClass_Windows_System_UserProfile_GlobalizationPreferences)
.Get(),
IID_PPV_ARGS(&gps));
if (FAILED(hr)) {
std::cerr << "RoGetActivationFactory failed" << std::endl;
return 1;
}
ComPtr<IVectorView<HSTRING>> langs;
hr = gps->get_Languages(&langs);
if (FAILED(hr)) {
std::cerr << "Could not get Languages" << std::endl;
return 1;
}
uint32_t size;
hr = langs->get_Size(&size);
if (FAILED(hr)) {
std::cerr << "Could not get Size" << std::endl;
return 1;
}
for (uint32_t i = 0; i < size; ++i) {
HString lang;
hr = langs->GetAt(i, lang.GetAddressOf());
if (FAILED(hr)) {
std::cerr << "Could not get Languages[" << i << "]" << std::endl;
continue;
}
std::wcout << lang.GetRawBuffer(nullptr) << std::endl;
}
}
I found out that language list returned by GetUserPreferredUILanguages() matters with your "Windows UI language" setting, and nothing to do with "Input method list order".
For example, in following screenshot from Win10.21H2,
I can see GetUserPreferredUILanguages() return a list of three langtags:
fr-CA\0fr-FR\0en-US\0\0
In summary, for GetUserPreferredUILanguages() and GetUILanguageFallbackList() their returned langtag list is determined solely by current user's "Windows display language" selection. It is a user-wide single-selection setting. And, for a specific display-language selection, the list-items within and the order of the list-items are hard-coded by Windows itself. Yes, it is even unrelated to what "input methods(IME)" you have added to the control panel -- for example, you add "fr-CA" but not "fr-FR", and the fallback list will still be fr-CA\0fr-FR\0en-US\0\0.
The difference of the two APIs, according to my experiment, is that GetUILanguageFallbackList() returns neutral langtags("fr", "en" etc) as well, so it produces a superset of GetUserPreferredUILanguages().

SDL2: undefined references to strange functions

i have written this small piece of Code for testing purposes:
#include <iostream>
#include "SDL2/SDL.h"
int main(int argc, char* argv[]) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}
// Betriebssystem ermitteln
std::string PlatFormString;
PlatFormString = SDL_GetPlatform();
std::cout << PlatFormString << "\n";
// Separator ermitteln
char Separator = '/';
if (PlatFormString == "Windows") {
Separator = '\\';
}
std::cout << "Separator: " << Separator << "\n";
// Installationspfad ermitteln
std::string InstallPath;
InstallPath = SDL_GetBasePath();
std::cout << InstallPath << "\n";
// Benutzerverzeichnis ermitteln
char* UserPath;
UserPath = SDL_GetPrefPath("TFF", "Blaster");
if (UserPath == nullptr) {
std::cout << "No Userpath aviable !! \n";
}
else {
std::cout << UserPath << "\n";
}
SDL_Quit();
return 0;
};
Under Linux eerthing works fine.
But under Windows, i am getting these strange errors ...
-------------- Build: Debug in Test (compiler: GNU GCC Compiler)---------------
g++.exe -LD:\mingw64 -LD:\mingw64\bin -LD:\mingw64\include -LD:\mingw64\include\SDL2 -LD:\mingw64\lib -o bin\Debug\Test.exe obj\Debug\src\Test.o -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer ..\..\mingw64\lib\libSDL2main.a ..\..\mingw64\lib\libSDL2.a
..\..\mingw64\lib\libSDL2.a(SDL_systimer.o): In function `timeSetPeriod':
/Users/slouken/release/SDL/SDL2-2.0.3-source/foo-x64/../src/timer/windows/SDL_systimer.c:58: undefined reference to `__imp_timeBeginPeriod'
/Users/slouken/release/SDL/SDL2-2.0.3-source/foo-x64/../src/timer/windows/SDL_systimer.c:52: undefined reference to `__imp_timeEndPeriod'
/Users/slouken/release/SDL/SDL2-2.0.3-source/foo-x64/../src/timer/windows/SDL_systimer.c:58: undefined reference to `__imp_timeBeginPeriod'
and so on. I dont know whats going on there. Can anyone help ?
I#m using Codeblocks 13.12, minGW64 (4.8.1), SDL 2.0.3 and Windows 7 64bit
You need to link against winmm.lib.
Try adding
#pragma comment(lib, "winmm.lib")
to your source.
I am posting this about a year later but for the future searchers here is the solution. Replace libSDL2.a with libSDL2.dll.a and it will compile just fine. The issue has something to do with dynamic and static linking with a windows machine or something I personally do I understand it completely but it works.
I came across the solution by reading this article: http://tech.yipp.ca/sdl/how-to-fix-libsdla-undefined-reference/
However this goes on a whole other solution I read between the lines or more particularly.
This is a really a rare problem that would occur only when you try to link with libSDL.a static library instead of the dynamic library SDL.dll. Then you have to add those library that SDL.dll normally links against which are the three above.

boost library inside c++/cli.. exit with "code 0xC0020001: The string binding is invalid"

I am using the boost library for getting the current system time and my code works but visualt studio 2010 exits after the program.the debugger breaks while trying to free the non existing pointer. I know this is because of the boost native code.Since there is no error if I comment the boost portion of code.
Till now I tried using the #pragma as explained in MSDN but with no success.Can someone provide me some suggestions.? (I also tried GetSystemTime function to get the time but i cannot get the microsecond detail like boost.)
MY Code
#pragma managed(push, off)
void GetSystemDateTime(SDateTime& stimeblock);
#pragma managed(pop)
int main()
{
c++/cli code
SDateTime stimestruct[1];
//call to the function having the boost code..
GetSystemDateTime(stimestruct[0]);
}
Function Definition
#pragma managed(push, off)
void GetSystemDateTime(SDateTime& timeblock)
{
// SYSTEMTIME time;
// GetSystemTime(&time);
// WORD millis = (time.wSecond * 1000) + time.wMilliseconds;
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
std::tm pt_tm = to_tm(now);
std::cout << now << std::endl;
//std::cout << time.wYear<< time.wMonth<<time.wDay //<<time.wHour<<time.wMinute<<time.wSecond<<time.wMilliseconds << std::endl;
std::string timestring = to_iso_string(now);
std::string sYear = timestring.substr (0,4);
std::string sMonth = timestring.substr (4,2);
std::string sDay = timestring.substr (6,2);
std::string sHour = timestring.substr (9,2);
std::string sMinute = timestring.substr (11,2);
std::string sSecond = timestring.substr (13,2);
std::string sUSecond = timestring.substr (16);
istringstream isYear(sYear);
istringstream isMonth(sMonth);
istringstream isDay(sDay);
istringstream isHour(sHour);
istringstream isMinute(sMinute);
istringstream isSec(sSecond);
istringstream isUSec(sUSecond);
// use is like an input stream
int iYear,iMonth,iDay,iHour,iMinute,iSecond,iUSecond;
isYear >> iYear;
isMonth >>iMonth;
isDay >>iDay;
isHour >>iHour;
isMinute >>iMinute;
isSec >>iSecond;
isUSec >>iUSecond;
timeblock.uiYear = iYear;
timeblock.usiMonth = time.wMonth;
timeblock.usiDay = time.wDay;
timeblock.usiHour = time.wHour;
timeblock.usiMinute = time.wMinute;
timeblock.usiSec = time.wSecond;
timeblock.udiUSec = time.wMilliseconds;
// Display version information
}
I've seen this error caused by using a static variable in native code in a C++/CLI assembly.
The only workaround I found was to remove the static variable, e.g., by moving it to class or file scope.
However, if this static variable is in the boost code, doing so may not be easy/possible. In that case, you could create a separate C++ file that's compiled without /clr, use the boost function in that file, and link that into your C++/CLI assembly.
This error seems to be caused by the compiler generating incorrect code. I filed a bug with Microsoft, which was closed "won't fix", but the compiler team gave some other workarounds in their response.
Try using
#pragma managed(push, off)
#pragma managed(pop)
around the #include lines for all boost header files.
I'm on the same problem for a few days now.
this is the best workaround i have found. and also explains why this is happening.
look at the end (number 7 and 9)
hope this helps http://www.codeproject.com/Articles/442784/Best-gotchas-of-Cplusplus-CLI

Hello World on Visual Studio 2010 with Intel ArBB?

I'm trying to get started working with Intel's Array Building Blocks, and there seems to only be one tutorial on "Hello World", at http://www.hpc.lsu.edu/training/tutorials/sc10/tutorials/SC10Tutorials/docs/M07/M07.pdf . And I'm not really getting it.
I'm using Visual Studio 2010 and this is the code I got from the above link, kinda.
#include <C:/Program Files/intel/arbb/Beta6/include/arbb.hpp>
//What do I have to do to make just "#include <arbb.hpp>" work?
using namespace arbb;
void my_function(f32& result, f32 input){
std::cout << "Hello, world!" << std::endl;
result = input + 1.0f; //"Error: no operator "+" matches these operands
}
int main(){
typedef closure<void (f32&, f32)> mfc;
mfc a = capture(my_function);
mfc b = call(my_function);
mfc c = call(my_function);
}
What else do I need to do to get "Hello World" working?
There are many samples available in arbb installation path. You can use the visual studio solution files to start with any of the sample. That is the easiest way.
In order to compile and run your own application from scratch, you have to have the include and dependencies set.
On Linux, you can add the path ~/(whatever)/intel/arbb/Beta6/include in the compile option using -I
On Windows, you can do:
set INCLUDE=C:/Program Files/intel/arbb/Beta6/include/arbb.hpp;
Or have a batch script that will ensure all the environment variables are set by default.
--- contents of the batch file ---
SET ARBB_OPT_LEVEL=O3
SET PATH=%ARBB_ROOT%\bin\ia32;%ARBB_ROOT%\bin\ia32\vs%MSVS_VERSION%;%OPENCV_ROOT%\bin;%FFTW_ROOT%;%FREEGLUT_ROOT%;%PTHREADS_ROOT%\lib;%PATH%
---- here is hello world program in arbb ---
#include <arbb.hpp>
void arbb_hello_map(arbb::i32& val)
{
val = val * 2;
}
void arbb_hello(arbb::dense<arbb::i32>& data)
{
using namespace arbb;
map(arbb_hello_map)(data);
}
int main()
{
using namespace arbb;
int size = 5;
dense<i32> data = dense<i32>(size);
range<i32> write_data = data.write_only_range();
for (int i = 0; i < size; ++i)
write_data[i] = i;
arbb::call(arbb_hello)(data);
std::cout << "hello: " << std::endl;
const_range<i32> read_data = data.read_only_range();
for (int i = 0; i < size; ++i)
std::cout <<"data["<<i<<"] = " << read_data[i] <<"\n";
return 0;
}
And compile it using
g++ -m64 -I/home/YOUR_NAME/arbb/install//include -Wall -Werror -O3 -W -Wshadow temp.cpp -o temp -L/home/YOUR_NAME/arbb/install/lib/intel64 -larbb_dev -ltbb -littnotify
Run it using
./temp

getline on MacOSX 10.6 crashing C compiler?

I'm having a really hard time getting an R library installed that requires some compilation in C. I'm using a Mac OSX Snow Leopard machine and trying to install this R package (here).
I've looked at the thread talking about getline on macs and have tried a few of these fixes, but nothing is working! I'm a newbie and don't know any C, so that may be why! Can anyone give me some tips on how I could modify files in this package to get it to install?? Anyhelp would be pathetically appreciated! Here's the error I'm getting:
** libs
** arch - i386
g++ -arch i386 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/i386 -I/usr/local/include -D_FASTMAP -DMAQ_LONGREADS -fPIC -g -O2 -c bed2vector.C -o bed2vector.o
In file included from /usr/include/c++/4.2.1/backward/strstream:51,
from bed2vector.C:8:
/usr/include/c++/4.2.1/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
bed2vector.C: In function ‘int get_a_line(FILE*, BZFILE*, int, std::string&)’:
bed2vector.C:74: error: no matching function for call to ‘getline(char**, size_t*, FILE*&)’
make: *** [bed2vector.o] Error 1
chmod: /Library/Frameworks/R.framework/Resources/library/spp/libs/i386/*: No such file or directory
ERROR: compilation failed for package 'spp'
The easiest solution is probably to add a static definition for getline() to bed2vector.c. This might be good enough:
/* PASTE AT TOP OF FILE */
#include <stdio.h> /* flockfile, getc_unlocked, funlockfile */
#include <stdlib.h> /* malloc, realloc */
#include <errno.h> /* errno */
#include <unistd.h> /* ssize_t */
extern "C" ssize_t getline(char **lineptr, size_t *n, FILE *stream);
/* PASTE REMAINDER AT BOTTOM OF FILE */
ssize_t
getline(char **linep, size_t *np, FILE *stream)
{
char *p = NULL;
size_t i = 0;
if (!linep || !np) {
errno = EINVAL;
return -1;
}
if (!(*linep) || !(*np)) {
*np = 120;
*linep = (char *)malloc(*np);
if (!(*linep)) {
return -1;
}
}
flockfile(stream);
p = *linep;
for (int ch = 0; (ch = getc_unlocked(stream)) != EOF;) {
if (i > *np) {
/* Grow *linep. */
size_t m = *np * 2;
char *s = (char *)realloc(*linep, m);
if (!s) {
int error = errno;
funlockfile(stream);
errno = error;
return -1;
}
*linep = s;
*np = m;
}
p[i] = ch;
if ('\n' == ch) break;
i += 1;
}
funlockfile(stream);
/* Null-terminate the string. */
if (i > *np) {
/* Grow *linep. */
size_t m = *np * 2;
char *s = (char *)realloc(*linep, m);
if (!s) {
return -1;
}
*linep = s;
*np = m;
}
p[i + 1] = '\0';
return ((i > 0)? i : -1);
}
This doesn't handle the case where the line is longer than the maximum value that ssize_t can represent. If you run into that case, you've likely got other problems.
Zeroth question: Have you considered using a package manager like fink or MacPorts rather than compiling yourself? I know that fink has an R package.
First question: How is the R build managed? Is there a ./configure? If so have you looked at the options to it? Does it use make? Scons? Some other dependency manager?
Second question: Have you told the build system that you are working on a Mac? Can you specify that you don't have a libc with native getline?
If the build system doesn't support Mac OS---but I image that R's does---you are probably going to have to download the standalone version, and hack the build to include it. How exactly you do that depends on the build system. And you may need to hack the source some.

Resources