How to bundle OpenSSL v3 binaries with application on Windows?

77 Views Asked by At

How to bundle OpenSSL v3 binaries with application on Windows?

Withing executable I have libcrypto-3-x64.dll and libssl-3-x64.dll.

In ./lib directory I have DLLs in engines-3 and ossl-modules.

Good, but to start application I forced to use *.bat file with something like:

set OPENSSL_MODULES=./lib/ossl-modules
set OPENSSL_ENGINES=./lib/engines-3
start "" my_app.exe %

How to avoid using of this *.bat file, and have only my_app.exe that won't produce Windows error message?

Want to add that:

int main( int argc, char ** argv )
{
    qputenv( "OPENSSL_MODULES", "./lib/ossl-modules" );
    qputenv( "OPENSSL_ENGINES", "./lib/engines-3" );

doesn't solve the problem.

And a following *.manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <environment name="OPENSSL_MODULES" value="./lib/ossl-modules" />
      <environment name="OPENSSL_ENGINES" value="./lib/engines-3" />
    </windowsSettings>
  </application>
</assembly>

doesn't solve the problem too.

Thanks.

1

There are 1 best solutions below

0
Andrew Henle On BEST ANSWER

If the bat file works but this code does not:

int main( int argc, char ** argv )
{
    qputenv( "OPENSSL_MODULES", "./lib/ossl-modules" );
    qputenv( "OPENSSL_ENGINES", "./lib/engines-3" );

that means you have to set the environment variables before the OS loads the process.

So do just that. Re-load the process after you set the envvals:

int main( int argc, char ** argv )
{
    QByteArray envval = qgetenv( "OPENSSL_MODULES" );

    // assumes a "default constructed" QByteArray will
    // return true here - not tested
    if ( ennval.isEmpty() )
    {
        qputenv( "OPENSSL_MODULES", "./lib/ossl-modules" );
        qputenv( "OPENSSL_ENGINES", "./lib/engines-3" );

        execv( argv[ 0 ], argv );
        perror( "execv" );
        exit( 1 );
    }
    .
    .
    .

Headers and error checking have been omitted to keep the code example short enough so it doesn't have a vertical scroll bar.

And turn off Microsoft's risible, "We've deprecated every portable non-Microsoft thing we can get away with" "warning"

Note that those envvals assume the current working directory is the parent of that particular lib directory. You can add quite a bit of robustness and remove the requirement by finding the absolute path of the application binary first and then use that to determine the absolute path to the lib directory.